图的连通性问题
posted on 2024-10-24 06:33:57 | under | source
根据 Alex_Wei 的博客写的。
无向图
基础定义:
- 割点(边):删去后原图连通分量增加的点(边)。
- 点(边)双连通分量:不存在割点(边)的连通分量。
- \(u,v\) 点(边)双连通:\(u,v\) 处于同一点(边)双连通分量中。
- \(u,v\) 的必经点(边):\(u,v\) 两点间所有路径的点(边)的交集。
必经点(边)与割点(边)之间的关系:必经点(边)一定是割点(边);若 \(u,v\) 原本连通,删去某割点(边)后变得不连通,则称该割点(边)为原图的必经点(边)。
注意,\(u,v\) 路径上的所有割边必然是 \(u,v\) 的必经边,但是割点不成立,容易举出反例。本质原因是 \(u,v\) 路径经过割边则删去割边后两点必然不连通,否则不是割边;但是经过割点不代表删掉它两点不连通。例如:\({(1,2),(2,3),(3,1),(3,4)}\)。
注意,孤立点不是割点,孤立边是割边。
基本性质:
-
割点:点双间的交点为割点,一个割点可能属于多个点双,其余点恰属于一个点双,所有分量的连接情况构成树形。
-
割边:边双间依靠割边连接,割边不属于任何边双,所有分量的连接情况构成树形。
-
除两点一线型,任意点双中任意两点间存在简单环,即存在至少两条点不重复(除起点终点)的路径。
-
任意边双中,任意两点存在回路,即存在至少两条边不重复的路径。
-
除两点一线型,点双必然是边双,点双可以继承边双的所有性质。
求割点、割边
考虑建 dfs 树,记 \(dfn_i\) 表示 \(i\) 的时间戳,\(low_i\) 表示 \(i\) 子树内所有点经过至多一条返租边能够到达的点的最小 \(dfn\)。
注意区分一下取不取等号:
-
割点的判定:对于非根节点 \(u\) 是割点,当且仅当存在儿子 \(v\),使得 \(low_v\ge dfn_u\);否则根为割点当且仅当其儿子个数 \(\ge 2\)。
-
割边的判定:显然 \((u,v)\) 是树边时才可能为割边,令 \(u\) 为 \(v\) 的父亲,则 \((u,v)\) 是割边当且仅当 \(low_v>dfn_u\)。
实际实现中,一般初始化 \(low_u=dfn_u\),这没有影响。转移:对于 \(u\),若 \(v\) 为 \(u\) 的儿子(即树边),则 \(low_u\gets low_v\),若 \((u,v)\) 是返租边,则 \(low_u\gets dfn_v\);
这里尤其注意下 \(v\) 是 \(u\) 父亲的情况,对于割点可以无脑更新,因为判定中取了等号。但是割边不行,必须判断是不是重边。
求点双、边双
dfs 时将点逐个弹进栈中,然后每次取栈顶的元素即可,感性理解就是不断剥叶子的过程。
-
点双:在求割点的过程中,假如 \(low_v\ge dfn_u\),就说明 \(u\) 和 \(v\) 残余子树构成一个点双,注意 \(u\) 可能属于多个点双。
-
注意,求点双时无需考虑根的特判,但是要处理孤立点(可能有自环)。
-
边双: 同点双,\((u,v)\) 是割边说明 \(v\) 的残余子树构成边双,大力弹出即可。注意最顶上的边双不一定被弹出,最后检查下即可。
圆方树
因为点双间靠点连接,所以不太好直接建图。于是令原图的点为圆点,方点为一个点双的代表节点(不属于原图),让方点向点双内所有圆点连边,构成圆方树,用于刻画点的必经性。
性质:原图删去 \(x\) 后其余点的连通性等于圆方树上删去 \(x\) 后其余点的连通性;圆方树上两点 \(x,y\) 的简单路径上所有圆点恰为原图上 \(x,y\) 间的所有必经点。
而且这玩意还能判断 \((u,v)\) 是不是割边:不考虑重边,则 \((u,v)\) 是割边当且仅当 \((u,v)\) 所在方点度数为 \(2\),即点双为两点一线。
有向图
基础定义:
- 强连通:\(u,v\) 两点互相可达。
- 强连通图:任意两点互相可达。
- 强连通分量:极大的强连通子图。
缩点
证明推导啥的太复杂了,直接放结论。
首先有向图 dfs 树比较复杂,会有:树边、返祖边、横叉边、前向边。我们需要额外记 \(vis_i\) 表示 \(i\) 是否在栈内,即是否还未确认属于哪个强连通分量。
转移若是树边直接 \(low_u\gets low_v\),否则若 \(v\) 不在栈中才 \(low_u\gets dfn_v\)。
最后我们考虑让一个强连通分量在其深度最小的子树上被统计,即 \(low_u=dfn_u\) 时。

浙公网安备 33010602011771号