无向图的双连通分量

点双连通分量模板(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], bccno[N], iscut[N], dfs_clock, bcc_cnt;
 7 vector<int> G[N], bcc[N]; 
 8 struct Edge {
 9     int u, v;
10 };
11 stack<Edge> S;
12 
13 int dfs(int u, int fa) {
14     int lowu = pre[u] = ++dfs_clock;
15     int child = 0;
16     for (int i = 0; i < G[u].size(); ++i) {
17         int v = G[u][i];
18         if (v == fa) continue;
19         Edge now = (Edge){u, v};
20         if (!pre[v]) {
21             S.push(now);
22             ++child;
23             int lowv = dfs(v, u);
24             lowu = min(lowu, lowv);
25             if (lowv >= pre[u]) {
26                 iscut[v] = true;
27                 ++bcc_cnt; bcc[bcc_cnt].clear();
28                 while (1) {
29                     Edge e = S.top(); S.pop();
30                     if (bccno[e.u] != bcc_cnt) {bcc[bcc_cnt].push_back(e.u); bccno[e.u] = bcc_cnt;}
31                     if (bccno[e.v] != bcc_cnt) {bcc[bcc_cnt].push_back(e.v); bccno[e.v] = bcc_cnt;}
32                     if (e.u == u && e.v == v) break;
33                 }
34             }
35         }
36         else if (pre[v] < pre[u]) {
37             S.push(now);
38             lowu = min(lowu, pre[v]);
39         }
40     }
41     if (fa < 0 && child == 1) iscut[u] = 0;
42     return lowu;
43 }
44 
45 void find_bcc(int n) {
46     M(pre, 0); M(iscut, 0); M(bccno, 0);
47     for (int i = 0; i < n; ++i)
48         if (!pre[i]) dfs(i, -1);
49 }
50 
51 int main() {
52     int n, m, u, v;
53     cin >> n >> m;
54     for (int i = 0; i < m; ++i) {
55         cin >> u >> v;
56         u--; v--;
57         G[u].push_back(v);
58         G[v].push_back(u);
59     }
60     find_bcc(n);
61     for (int i = 1; i <= bcc_cnt; ++i) {
62         for (int j = 0; j < bcc[i].size(); ++j)
63             cout << bcc[i][j]+1 << " ";
64         cout << endl;
65     }
66 
67     return 0;
68 }
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], bccno[N], dfs_clock, bcc_cnt;
 7 vector<int> G[N];
 8 
 9 stack<int> S;
10 int dfs(int u, int fa) {
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 (v == fa) continue;
16         if (!pre[v]) {
17             int lowv = dfs(v, u);
18             lowu = min(lowu, lowv);
19         }
20         else lowu = min(lowu, pre[v]);
21     }
22     if (lowu == pre[u]) {
23         ++bcc_cnt;
24         while (1) {
25             int k = S.top(); S.pop();
26             bccno[k] = bcc_cnt;
27             if (k == u) break; 
28         }
29     }
30     return lowu;
31 }
32 
33 void find_bcc(int n) {
34     M(pre, 0); M(bccno, 0); dfs_clock = bcc_cnt = 0;
35     for (int i = 0; i < n; ++i)
36         if (!pre[i]) dfs(i, -1);
37 }
38 
39 
40 int main() {
41     int n, m, u, v;
42     cin >> n >> m;
43     for (int i = 0; i < m; ++i) {
44         cin >> u >> v;
45         u--; v--;
46         G[u].push_back(v);
47         G[v].push_back(u);
48     }
49     find_bcc(n);
50 
51     return 0;
52 }
View Code

 

posted @ 2017-04-13 21:44  Robin!  阅读(226)  评论(0编辑  收藏  举报