点双
vector<int> G[maxn], bcc[maxn]; int n, m, dfstime, bcccnt; bool iscut[maxn]; int bccnu[maxn], pre[maxn]; stack<pair<int, int> > s; int dfs(int u, int fa){ int lowu = pre[u] = ++dfstime; int child = 0; int len = G[u].size(); for (int i = 0; i < len; i++){ int v = G[u][i]; pair<int, int> p = mk(u, v); if (pre[v] == -1){ child++; s.push(p); int lowv = dfs(v, u); lowu = min(lowu, lowv); if (lowv >= pre[u]){ iscut[u] = true; bcccnt++; while (true){ pair<int, int> pr = s.top(); s.pop(); if (bcccnt != bccnu[pr.fi]) bccnu[pr.fi] = bcccnt, bcc[bcccnt].pb(pr.fi); if (bcccnt != bccnu[pr.se]) bccnu[pr.se] = bcccnt, bcc[bcccnt].pb(pr.se); if (pr.fi == u && pr .se == v) break; } } } else if (pre[v] < pre[u] && v != fa){ s.push(p); lowu = min(lowu, pre[v]); } } if (fa < 0 && child == 1) iscut[u] = false; return lowu; } void find_bcc(){ dfstime = bcccnt = 0; memset(iscut, false, sizeof(iscut)); memset(bccnu, 0, sizeof(bccnu)); memset(pre, -1, sizeof(pre)); dfs(1, -1); }
边双
stack<int> s; vector<int> G[maxn], bcc[maxn]; int bccno[maxn], pre[maxn], iscut[maxn]; int n, m, bcc_cnt, dfstime; int dfs(int u, int fa){ int lowu = pre[u] = ++dfstime; int len = G[u].size(); int child = 0; s.push(u); for (int i = 0; i < len; i++){ int v = G[u][i]; if (pre[v] == -1){ child++; int lowv = dfs(v, u); lowu = min(lowv, lowu); if (lowv > pre[u]){ iscut[u] = true; } } else if (pre[v] < pre[u] && v != fa){ lowu = min(lowu, pre[v]); } } if (lowu == pre[u]){ bcc_cnt++; while (true){///边双连通分量是不存在重点的 int v = s.top(); s.pop(); bcc[bcc_cnt].pb(v); if (v == u) break; } } if (fa == -1 && child == 1) iscut[u] = false; return lowu; }