码迷,mamicode.com
首页 > 编程语言 > 详细

【模板】强连通分量和tarjan算法

时间:2016-06-28 20:17:25      阅读:211      评论:0      收藏:0      [点我收藏+]

标签:

  看了好久才终于明白了这个算法。。复杂度是O(n+m)。

  我觉得这个算法不是很好理解,但是看懂了以后还是觉得听巧妙的。

  下面给出模板代码和三组简单数据帮助理解。

  代码如下:

 

 1 #include <stdio.h>
 2 #include <stack>
 3 #include <algorithm>
 4 #include <string.h>
 5 #include <vector>
 6 using namespace std;
 7 
 8 const int N = 100+5;
 9 
10 stack<int> S;
11 int scc_cnt;  //强连通分量的个数
12 int tot;    //访问到该节点的时间戳
13 int belong[N];  //belong[i]表示i节点所属于第几个强连通分量
14 int dfn[N];     //表示第i个节点被访问的时间
15 int low[N];    //表示第i个节点的子节点所能访问到的最小的dfn值
16 vector<int> G[N];
17 
18 void dfs(int u)
19 {
20     dfn[u] = low[u] = ++tot;
21     S.push(u);
22     for(int i=0;i<G[u].size();i++)
23     {
24         int v = G[u][i];
25         if(!dfn[v])
26         {
27             dfs(v);
28             low[u] = min(low[u],low[v]);
29         }
30         else if(!belong[v]) //这句话等价于v在栈内
31         {
32             low[u] = min(low[u],low[v]);
33             //low[u] = min(low[u],dfn[v]);
34             //上面两种写法似乎都是没有问题的,但是如果仔细斟酌第三组数据和low的定义的话
35             //似乎是上面的写法更好,这里不敢确定,留个疑问。
36         }
37     }
38     if(low[u]==dfn[u])
39     {
40         scc_cnt++;
41         for(;;)
42         {
43             //因为元素x只有在出栈了以后才被赋予归属,所以这就是上面等价的原因
44             int x = S.top();S.pop();
45             belong[x] = scc_cnt;
46             if(x==u) break;
47         }
48     }
49 }
50 
51 void scc(int n)
52 {
53     memset(dfn,0,sizeof(dfn));
54     memset(belong,0,sizeof(belong));
55     tot = scc_cnt = 0;
56     for(int i=0;i<n;i++)
57     {
58         if(!dfn[i]) dfs(i);
59     }
60 }
61 
62 int main()
63 {
64     int n,m;
65     scanf("%d%d",&n,&m);
66     for(int i=0;i<m;i++)
67     {
68         int a,b;
69         scanf("%d%d",&a,&b);
70         G[a].push_back(b);
71     }
72     scc(n);
73     puts("");
74     for(int i=0;i<n;i++) printf("%d %d %d %d\n",i,belong[i],dfn[i],low[i]);
75     printf("%d\n",scc_cnt);
76     return 0;
77 }

 

  三组数据如下:

 

6 6
0 1
1 2
2 5
0 3
3 4
4 5
 
4 4
0 1
1 2
2 3 
3 0

6 8
0 1
0 2
2 3 
1 3
3 0
2 4
4 5
3 5

 

【模板】强连通分量和tarjan算法

标签:

原文地址:http://www.cnblogs.com/zzyDS/p/5624711.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!