tarjan

发布时间 2024-01-07 19:40:44作者: SunsetLake

link

@LHTCFLS :https://www.luogu.com.cn/blog/436107/tarjan-xue-xi-bi-ji

强连通分量

\(low\)\(x\) 最多经过一条返祖边能走到栈中的节点的最小 \(dfn\) 为多少。

\(low_x=dfn_x\) 时,对于一个 SCC 内某个最大环的 \(dfn\) 最小即深度最小的祖先 \(x\),在 dfs 回溯时若 \(dfn_x=low_x\),则可说明该点不能通过返祖边到达 \(dfn\) 更小的祖先,自己或者和自己 dfs 子树中的部分点构成一个 SCC。

边双连通分量

P8436

先找桥。\(low\) 的新定义应为最多经过一条非指向父亲的返祖边能走到的 \(dfn\) 最小的结点为多少。

\(low_v<dfn_u\) 时,若 \(v\) 不走 \((u,v)\) 这条边便永远到不了更上面的点,此时断开 \((u,v)\) 图不在连通。因此找到了一个 e-dcc。

但是如果不忽略指向父亲的返祖边,会导致每一条树边的 \((u,v)\) 都满足 \(dfn_u \ge low_v\)。因为对于 \(v\) 来说,\((v,u)\) 是一条返祖边,\(low_v\) 会被更新为 \(dfn_u\),接下来更新只会越来越小,因此即使 \((u,v)\) 是桥,在不忽略指向父亲的返祖边的情况下,也会被判定为非桥,这就是在求桥时 \(low\) 的定义要发生改变的原因。

注意存边从 \(2\) 开始,这样异或就能看出是否是指向父亲的返祖边。

点双连通分量

P8435

找割点。

\(low_v \ge dfn_u\) ,则 \(v\) 要想再往上必须要经过 \(u\) ,此时断掉 \(u\) 图不再连通,找到一个 v-dcc。

然而如果 \(u\) 是根节点事情就不对了,因为 \(u\) 没有父节点,他的 \(dfn\) 一定是最小的,但是某些情况 \(u\) 并不是割点。只有\(u\)\(\ge\) 两个儿子时才会是割点,因为无向图不存在横插边和前向边,因此两儿子相互独立,只有经过 \(u\) 才能到达。因此 \(u\) 是割点。

缩点

P3387

找强连通分量,将无向图变为 DAG 再干事。