模板强连通分量和tarjan算法

Posted Storm_Spirit

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板强连通分量和tarjan算法相关的知识,希望对你有一定的参考价值。

  看了好久才终于明白了这个算法。。复杂度是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算法的主要内容,如果未能解决你的问题,请参考以下文章

强连通分量——tarjan算法

HDU 1269 迷宫城堡 tarjan算法求强连通分量

强连通分量Tarjan算法模板

强连通分量tarjan模板复习

tarjan强连通分量缩点模板

tarjan算法——强连通分量