rt,下面是两个我见到过的写法:
第一个只记录根节点的子节点数
第二个会记录每个节点的子节点数
void tarjan(int now, const int& root) {
low[now] = dfn[now] = ++id;
int child = 0; // 累计该节点有几个儿子
for (int ch : edge[now]) {
if (!dfn[ch]) {
// 没有访问过 直接tarjan它
tarjan(ch, root);
low[now] = std::min(low[now], low[ch]);
if (now == root)
child++;
// 相较于缩点,割点在这里就可以判断
if (low[ch] >= dfn[now]) {
// 对于根节点,儿子大于1;对于其他点,直接更新
if (root != now || child > 1) {
is_cut[now] = 1;
}
}
} else
low[now] = std::min(low[now], dfn[ch]);
// low存储**不经过**父亲节点可以抵达的最早节点
// 如果右边ch的dfn写成low 而low可能会被更新得比dfn更小
// 那么这样处理得到的low 事实上是经过了父亲节点的
}
}
void tarjan(int now, const int& root) {
low[now] = dfn[now] = ++id;
int child = 0; // 累计该节点有几个儿子
for (int ch : edge[now]) {
if (!dfn[ch]) {
// 没有访问过 直接tarjan它
tarjan(ch, root);
low[now] = std::min(low[now], low[ch]);
// 相较于缩点,割点在这里就可以判断
if (low[ch] >= dfn[now]) {
child++;
// 对于根节点,儿子大于1;对于其他点,直接更新
if (root != now || child > 1) {
is_cut[now] = 1;
}
}
} else
low[now] = std::min(low[now], dfn[ch]);
// low存储**不经过**父亲节点可以抵达的最早节点
// 如果右边ch的dfn写成low 而low可能会被更新得比dfn更小
// 那么这样处理得到的low 事实上是经过了父亲节点的
}
}