int dfn[maxn], low[maxn], bl[maxn], scc, W[maxn]; bool ins[maxn]; stack<int> S; voidtarjan(int u){ staticint cnt = 0; dfn[u] = low[u] = ++cnt; ins[u] = 1; S.push(u); for (int i = head[u]; ~i; i = e[i].next) { int v = e[i].to; if (!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]); elseif (ins[v]) low[u] = min(low[u], dfn[v]); } if (dfn[u] == low[u]) { int t; ++scc; do { t = S.top(); S.pop(); bl[t] = scc; } while (t != u); } }
割点
定义
若删除某点后,原连通图分割成多个子图,则称该点为割点
算法
注意根节点要特判
1 2 3 4 5 6 7 8 9 10 11 12 13 14
int dfn[maxn], low[maxn]; bool ans[maxn]; voidtarjan(int u, int fa){ staticint cnt = 0; dfn[u] = low[u] = ++cnt; int du = 0; for (int i = head[u]; ~i; i = e[i].next) { int v = e[i].to; if (v == fa) continue; if (!dfn[v]) { ++du; tarjan(v, u); low[u] = min(low[u], low[v]); if (low[v] >= dfn[u] && fa) ans[u] = 1; } else low[u] = min(low[u], dfn[v]); } if (!fa && du > 1) ans[u] = 1; }
int dfn[maxn], low[maxn], dcc; bool ist[maxn]; vector<int> A[maxn]; stack<int> S; voidtarjan(int u, int fa){ staticint cnt = 0; dfn[u] = low[u] = ++cnt; S.push(u); int du = 0; for (int i = head[u]; ~i; i = e[i].next) { int v = e[i].to; if (v == fa) continue; if (!dfn[v]) { ++du; tarjan(v, u); low[u] = min(low[u], low[v]); if (low[v] >= dfn[u]) { ++dcc; int t; do { t = S.top(); S.pop(); A[dcc].push_back(t); } while (t != v); A[dcc].push_back(u); if (fa) ist[u] = 1; } } else low[u] = min(low[u], dfn[v]); } if (!fa && du > 1) ist[u] = 1; }