初识Tarjan算法

 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 }

 

posted @ 2018-05-02 20:40  MekakuCityActor  阅读(151)  评论(0编辑  收藏  举报