void tarjan(int u) {
dfn[u] = low[u] = ++times;
stk[++top] = u;instk[u] = 1;
for (int i = h[u]; i != -1; i = ne[i]) {
int v = to[i];
if (!dfn[v]) {
tarjan(v);
low[u] = min(low[u], low[v]);
}
else if (instk[u]) low[u] = min(low[u], dfn[v]);
}
if (dfn[u] == low[u]) {
++scc_cnt;
while (1) {
int v = stk[top--];
Size[scc_cnt] ++;
id[v] = scc_cnt;
instk[v] = 0;
if (v == u)break;
}
}
}
void tarjan(int u, int from) {
dfn[u] = low[u] = ++times;
stk[++top] = u;
bool flag = 1;
for (int i = h[u]; i != -1; i = ne[i])
{
int v = to[i];
if ((i^1) == from && flag) {flag = 0;continue;}//重边
if (!dfn[v]) {
tarjan(v, i);
low[u] = min(low[u], low[v]);
if (low[v] > dfn[u]) {
ans++;//i和i^1是桥。
}
} else
low[u] = min(low[u], dfn[v]);
}
if (low[u] == dfn[u]) {
e_dcc++;
while (1) {
id[stk[top]] = e_dcc;
if (stk[top--] == u)break;
}
}
}
void tarjan(int u, int fa) {
dfn[u] = low[u] = ++times;
stk[++top] = u;
int cnt = 0;
for (int i = h[u]; i != -1; i = ne[i])
{
int v = to[i];
if (!dfn[v]) {
tarjan(v, fa), ++cnt;
low[u] = min(low[u], low[v]);
if (low[v] >= dfn[u]) {
if (u != fa)cut[u] = 1;
else cut[u] |= (cnt > 1);
++dcc;
while (1) {
bl[stk[top]].push_back(dcc);//可以bl[dcc].push_back(stk[top]);
//主要是看自己需要啥,就咋写
sz[dcc]++;
if (stk[top--] == v)break;//这里确实有点不好理解,就是说,他这团是把当前这一团外面那一团给算上的,下次补一下图咕咕咕。
}
bl[u].push_back(dcc);
sz[dcc]++;
}
} else
low[u] = min(low[u], dfn[v]);
}
}
原文:https://www.cnblogs.com/Xiao-yan/p/14633093.html