点双连通分量模板(Tarjan算法)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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 }
边双连通分量模板(Tarjan算法)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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 }