有向图的强连通分量

两次dfs模板:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define INF 0x3f3f3f3f
 4 #define M(a, b) memset(a, b, sizeof(a))
 5 const int N = 1000 + 5;
 6 int vis[N], sccno[N], scc_cnt;
 7 vector<int> G[N], G2[N];
 8 vector<int> S;
 9 
10 void dfs1(int u) {
11     if (vis[u]) return;
12     vis[u] = 1;
13     for (int i = 0; i < G[u].size(); ++i) dfs1(G[u][i]);
14     S.push_back(u);
15 }
16 
17 void dfs2(int u) {
18     if (sccno[u]) return;
19     sccno[u] = scc_cnt;
20     for (int i = 0; i < G[u].size(); ++i) dfs2(G[u][i]);
21 }
22 
23 void find_scc(int n) {
24     M(vis, 0); M(sccno, 0);
25     S.clear(); scc_cnt = 0;
26     for (int i = 0; i < n; ++i) dfs1(i);
27     for (int i = n-1; i >= 0; --i) 
28         if (!sccno[i]) {++scc_cnt; dfs2(i);}
29 }
30 
31 int main() {
32     int n, m;
33     while (cin >> n >> m) {
34         int u, v;
35         for (int i = 0; i < m; ++i) {
36             cin >> u >> v;
37             G[u].push_back(v);
38             G2[v].push_back(u);
39         }
40         find_scc(n);        
41     }
42 
43     return 0;
44 }
View Code

 

Tarjan算法模板:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define M(a, b) memset(a, b, sizeof(a))
 4 #define INF 0x3f3f3f3f
 5 const int N = 1000 + 5;
 6 int pre[N], sccno[N], dfs_clock, scc_cnt;
 7 vector<int> G[N];
 8 stack<int> S;
 9 
10 int dfs(int u) {
11     int lowu = pre[u] = ++dfs_clock;
12     S.push(u);
13     for (int i = 0; i < G[u].size(); ++i) {
14         int v = G[u][i];
15         if (!pre[v]) {
16             int lowv = dfs(v);
17             lowu = min(lowu, lowv);
18         }
19         else if (!sccno[v]) { //加这个判定条件去掉已经包含在其他强连通分量中的反向边
20             lowu = min(lowu, pre[v]);
21         }
22     }
23     if (lowu == pre[u]) {
24         ++scc_cnt;
25         while (true) {
26             int x = S.top(); S.pop();
27             sccno[x] = scc_cnt;
28             if (x == u) break;
29         }
30     }
31     return lowu;
32 }
33 
34 void find_scc(int n) {
35     M(pre, 0); M(sccno, 0);
36     dfs_clock = scc_cnt = 0;
37     for (int i = 0; i < n; ++i) 
38         if (!pre[i]) dfs(i); 
39 }
40 
41 int main() {
42     int n, m;
43     while (cin >> n >> m) {
44         int u, v;
45         for (int i = 0; i < m; ++i) {
46             cin >> u >> v;
47             G[u].push_back(v);
48         }
49         find_scc(n);        
50     }
51 
52     return 0;
53 }
View Code

 

posted @ 2017-04-15 21:39  Robin!  阅读(129)  评论(0编辑  收藏  举报