無向圖的割點和橋 tarjan 模板
阿新 • • 發佈:2019-02-10
#include <bits/stdc++.h> using namespace std; const int MAXN = 20005; const int MAXM = 100005; int n, m, fir[MAXN], nxt[MAXM<<1], to[MAXM<<1], cnt=1; int dfn[MAXN], low[MAXN], tot; int cur, Ans[MAXN]; bool is_bridge[MAXM<<1]; void tarjan(int u, int ff) { dfn[u] = low[u] = ++tot; int out = 0; bool flag = 0; for(int i = fir[u]; i; i = nxt[i]) if(!dfn[to[i]]) { out++, tarjan(to[i], i), low[u] = min(low[u], low[to[i]]); if(dfn[u] <= low[to[i]]) flag = 1; //存割點 if(dfn[u] < low[to[i]]) is_bridge[i] = 1; //存橋 } else if((i^1) != ff) low[u] = min(low[u], dfn[to[i]]); if(!ff && out == 1) flag = 0; if(flag) Ans[++cur] = u; } void Add(int u, int v) { to[++cnt] = v; nxt[cnt] = fir[u]; fir[u] = cnt; } int main () { int x, y; scanf("%d%d", &n, &m); for(int i = 1; i <= m; i++) scanf("%d%d", &x, &y), Add(x, y), Add(y, x); for(int i = 1; i <= n; i++) if(!dfn[i]) tarjan(i, 0); printf("%d\n", cur); sort(Ans + 1, Ans + cur + 1); for(int i = 1; i <= cur; i++) // 輸出割點 printf("%d%c", Ans[i], i == n ? '\n' : ' '); }