割点/割边
void dfs(int x, int fa) {
dfn[x] = low[x] = ++ tot;
for(unsigned int i = 0; i < v[x].size(); i ++) {
int Y = v[x][i]; if(Y == fa) continue;
if(!dfn[Y]) { // 树边
dfs(Y, x); low[x] = Min(low[Y], low[x]);
if(low[Y] >= dfn[x]) (~fa) ? vis[x] = 1 : rts ++;
if(low[Y] > dfn[x]) cnt2 ++;
}
else low[x] = Min(dfn[Y], low[x]);
}
}
强连通
void dfs(int x) {
dfn[x] = ++ tot; low[x] = tot; s[++ cnt] = x;
for(uint i = 0; i < v[x].size(); i ++) {
int y = v[x][i];
if(!dfn[y]) dfs(y), low[x] = min(low[x], low[y]);
else if(!col[y]) low[x] = min(low[x], dfn[y]);
}
if(dfn[x] == low[x]) {
nk ++; int t;
do {
t = s[cnt --]; col[t] = nk;
} while(t != x);
}
}
边双
void dfs(int x, int fa) { // 缩点
s.push(x); dfn[x] = low[x] = ++ tot;
for(int i = Head[x]; i; i = Next[i]) {
int Y = Ver[i]; if(Y == fa) continue;
if(!dfn[Y]) {
dfs(Y, x); low[x] = Min(low[x], low[Y]);
}
else low[x] = Min(low[x], dfn[Y]);
}
if(dfn[x] == low[x]) {
cnt ++;
int t;
do {
t = s.top(); s.pop(); color[t] = cnt;
} while(t != x);
}
}
点双(待更新)