Taijin
定义
无向图
给定无向连通图 \(G=(V,E)\)。
若对于 \(x \in V\),从图中删去节点 \(x\) 以及所有与 \(x\) 相连的边之后,\(G\) 分裂成两个或以上不相连的子图,则称 \(x\) 为 \(G\) 的割点。
若对于 \(e \in E\),从图中边 \(e\) 之后,\(G\) 分裂成两个不相连的子图,则称 \(e\) 为 \(G\) 的桥或割边。
没有割点的无向连通图称为“点双连通图”。没有桥的无向连通图称为“边双连通图”。
无向图的极大点双连通子图被称为“点双连通分量”(v-DCC),无向图的极大边双连通子图被称为“边双连通分量”(e-DCC)。二者统称为“双连通分量”(DCC)。
\(dfn_x\) 表示 \(x\) 的 dfs 序。
\(low_x\) 表示 \(x\) 的子树中只经过一条边所到达的节点 \(dfn\) 的最小值。
有向图
Tarjin 算法
求强连通分量
当 \(dfn_x = low_x\) 时弹栈。
缩完点后是 DAG(有向无环图)。
求割点
\(x\) 为割点的充要条件是:
- 若 \(x\) 不为搜索树的根节点,存在 \(x\) 的一个子节点 \(y\),满足\(dfn_x \leq low_y\)
- 若 \(x\) 为搜索树的根节点,存在至少 \(2\) 个 \(x\) 的子节点满足上述条件
求桥
无向边 \((x,y)\) 是桥的充要条件是搜索树上存在 \(x\) 的一个子节点 \(y\) 满足 \(dfn_x < low_y\)。
求点双连通分量
- 当一个节点第一次访问时,把它入栈。
- 当存在 \(x\) 的子节点 \(y\) 满足 \(dfn_x \leq low_y\),无论下 \(x\) 是否为根,弹出栈内节点直到 \(y\) 被弹出,刚才弹出的所有结点和 \(x\) 构成的 v-DCC。
缩完点后可以构造出圆方树。
求边双连通分量
两种方法:
(1)把所有桥删去,跑连通块。
(2)每次把当前节点入栈。遍历完 \(x\) 后,若 \(dfn_x = low_x\),弹出栈内元素直到 \(x\) 被弹出,刚才弹出的所有结点构成一个 e-DCC。
缩完点后是一个树。
易错点
-
求 e-DCC 时不用判重边自环,但要判断父节点的反边。求 v-DCC 时要判自环,否则判孤立点时会出问题(似乎可以在判孤立点时判断,但输入时判断更简便),不用判重边和父节点。
-
求 v-DCC 时满足 \(dfn_x \leq low_y\) 时即可输出点双联通分量。求割点时当 \(x\) 为根节点时,至少要有 \(2\) 个 \(y\) 满足条件。
-
多测时清空 \(dfn\) 数组。
-
求删去一个点后会多出几个连通块时,答案不是这个点是否时割点,而是这个点被多少个 v-DCC 所包含(再减一)。