求割点和点双连通分量
const int maxn = 1010; vector <int> a[maxn], bcc[maxn]; int pre[maxn]; int low[maxn]; bool iscut[maxn]; int bccno[maxn]; int cnt[maxn]; int dfs_clock; int bcc_cnt; int n; struct Edge { int u, v; }; stack <Edge> S; int dfs(int u, int fa) { int lowu = pre[u] = ++dfs_clock; int child = 0; for(int i = 0; i < a[u].size(); i++) { int v = a[u][i]; Edge e = (Edge){u, v}; if(!pre[v]) { S.push(e); child++; int lowv = dfs(v, u); lowu = min(lowu, lowv); if(lowv >= pre[u]) { iscut[u] = true; bcc_cnt++; bcc[bcc_cnt].clear(); cnt[u]++; while(1) { Edge x = S.top(); S.pop(); if(bccno[x.u] != bcc_cnt) { bcc[bcc_cnt].push_back(x.u); bccno[x.u] = bcc_cnt; } if(bccno[x.v] != bcc_cnt) { bcc[bcc_cnt].push_back(x.v); bccno[x.v] = bcc_cnt; } if(x.u == u && x.v == v) break; } } } else if(pre[v] < pre[u] && v != fa) { S.push(e); lowu = min(lowu, pre[v]); } } if(fa < 0 && child == 1) { iscut[u] = false; cnt[u] = 0; } if(fa < 0 && child > 1) { iscut[u] = true; cnt[u] = child; } else if(cnt[u] > 0) cnt[u]++; return lowu; } void find_bcc() { memset(cnt, 0, sizeof(cnt)); memset(pre, 0, sizeof(pre)); memset(iscut, 0, sizeof(iscut)); memset(bccno, 0, sizeof(bccno)); dfs_clock = bcc_cnt = 0; dfs(1, -1); }
求桥和双连通
#include <cstdio> #include <cstring> #include <vector> #include <stack> #include <algorithm> using namespace std; const int maxn = 5010; vector <int> G[maxn]; bool ok[maxn][maxn]; int pre[maxn]; int low[maxn]; int sccno[maxn]; int dfs_clock; int scc_cnt; stack <int> S; int n, m; int degree[maxn]; int Topo[maxn][maxn]; void dfs(int u, int fa) { pre[u] = low[u] = ++dfs_clock; S.push(u); for(int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if(v == fa) continue; if(!pre[v]) { dfs(v, u); low[u] = min(low[u], low[v]); } else low[u] = min(low[u], pre[v]); } if(low[u] == pre[u]) { scc_cnt++; while(1) { int x = S.top(); S.pop(); sccno[x] = scc_cnt; if(x == u) break; } } } void find_scc() { dfs_clock = scc_cnt = 0; memset(sccno, 0, sizeof(sccno)); memset(pre, 0, sizeof(pre)); for(int i = 1; i <= n; i++) if(!pre[i]) dfs(i, -1); }
const int maxn = 10010; struct Edge { int u, v; Edge(){} Edge(int u, int v): u(u), v(v){} }; vector <int> a[maxn]; int pre[maxn]; int low[maxn]; int bccno[maxn]; Edge cnt[maxn]; int dfs_clock; int bcc_cnt; int bri; int n, m; stack <Edge> S; bool cmp(Edge a, Edge b) { if(a.u != b.u) return a.u < b.u; return a.v < b.v; } void dfs(int u, int fa) { low[u] = pre[u] = ++dfs_clock; for(int i = 0; i < a[u].size(); i++) { int v = a[u][i]; //if(v == fa) // continue; if(!pre[v]) { dfs(v, u); low[u] = min(low[u], low[v]); if(low[v] > pre[u]) { if(u < v) { cnt[bri].u = u; cnt[bri].v = v; } else { cnt[bri].u = v; cnt[bri].v = u; } bri++; } } else if(v != fa) low[u] = min(low[u], pre[v]); } } void find_bcc() { memset(pre, 0, sizeof(pre)); memset(bccno, 0, sizeof(bccno)); dfs_clock = bcc_cnt = bri = 0; for(int i = 0; i < n; i++) if(!pre[i]) dfs(i, -1); }
原文地址:http://blog.csdn.net/u011686226/article/details/29182991