1 int N,M;
2 int ver[maxn],Next[maxn],head[maxn],dfn[maxn],low[maxn];
3 int Gver[maxn],GNext[maxn],Ghead[maxn],Gtot;
4 int stack[maxn],ins[maxn],c[maxn];
5 vector<int> scc[maxn];
6 int tot,top,cnt,nm;
7 //cnt个强连通分量,scc[i]记录编号为i的强连通分量中的所有节点,c[x]表示x所在连通分量地区
8 void addori(int x,int y)
9 {
10 ver[++tot] = y,Next[tot] = head[x],head[x] = tot;
11 }
12 void tarjan(int x)
13 {
14 dfn[x] = low[x] = ++nm;
15 stack[++top] = x,ins[x] = 1;
16 for(int i = head[x]; i; i = Next[i])
17 {
18 int y = ver[i];
19 if(!dfn[y])
20 {
21 tarjan(y);
22 low[x] = min(low[x],low[y]);
23 }
24 else if(ins[y])
25 low[x] = min(low[x],dfn[y]);
26 }
27 if(dfn[x] == low[x])
28 {
29 cnt ++;
30 int y;
31 do
32 {
33 y = stack[top --],ins[y] = 0;
34 c[y] = cnt,scc[cnt].pb(y);
35 }
36 while(x != y);
37 }
38 }
39 void addAft(int x,int y)
40 {
41 Gver[++Gtot] = y;
42 GNext[Gtot] = Ghead[x];
43 Ghead[x] = Gtot;
44 }
45 void Shrink()
46 {
47 _for(i,1,N+1)
48 if(!dfn[i])
49 tarjan(i);
50
51 _for(x,1,N+1)
52 for(int i = head[x]; i; i = Next[i])
53 {
54 int y = ver[i];
55 if(c[x]==c[y]) continue;
56 addAft(c[y],c[x]);
57 }
58 }