1 #include<bits/stdc++.h>
2 using namespace std;
3 const int maxn=100005;
4 int cnt=0;//强连通分量的个数
5 int stk[maxn];//暂时存放遍历过的点,在遇到low[x]==dfn[x]时向外抛出元素
6 int dfn[maxn];//时间戳[由于每个点最多属于一个强连通分量,所以也用来区分是否已经存在于一个强连通分量了,如果存在就没必要继续向下查找了]
7 int low[maxn]//和最早祖先的时间
8 int vis[maxn];//标记本次遍历过程入栈的点,在stk[]抛出点时同时清除标记的印记
9 int sz[maxn];//每个强连通分量内元素的个数
10 int tim=1;
11 void tar(int x)
12 {
13 low[x]=dfn[x]=tim++;
14 vis[x]=1;
15 stk[tot++]=x;
16 if(!dfn[next[x]])
17 {
18 tar(next[x]);
19 low[x]=min(low[x],low[next[x]]);
20 }
21 else if(vis[next[x]])
22 {
23 low[x]=min(low[next[x]],low[x]);
24 }
25 if(dfn[x]==low[x])
26 {
27 int xx;
28 cnt++;
29 do{
30 xx=stk[--tot];//抛出元素
31 col[xx]=cnt;//涂色分块
32 sz[cnt]++;//元素所在强连通分量内元素的个数
33 vis[xx]=0;//清除标记
34 }while(x!=xx);
35 }
36 }
37 int main()
38 {
39 for(int i = 1 ; i <= n ; i++)
40 {
41 tar(i);
42 }
43 return 0;
44 }
