概念解释
- 连通分量:无向图的极大连通子图。连通图的连通分量是其自身,非连通图有多个连通分量
- 割边(桥):一无向图中,一条边称为桥应当满足当删除这条边后,图的连通分量增多
- 割点:一无向图中,一个点称为割点应当满足当删除这个顶点和与其相关联的边后,图的连通分量增多
分类
- 边双连通分量:一连通分量称之为边连通分量,应当满足去掉任意一条边,都不会改变此图的连通性,即不存在桥
- 点双连通分量:一连通分量称之为点连通分量,应当满足去掉任意一个点后,都不会改变此图的连通性,即不存在割点
桥和割点的判定思路
桥
与有向图求scc类似,同样引入\(dfn\)和\(low\)两个标记。对于(x, y),如果x->y是桥,应当满足\(low[y] > dfn[x]\)
注:
- 此时为无向图,同时存在父->子,子->父两条路径,在Tarjan过程中,必须保证一条边不能重复走,因为桥的判定条件为\(low[y] > dfn[x]\),如果可以重复走,则至少可以满足\(low[y] >= dfn[x]\),无法再判定出桥的存在了
在有向图中,存在一种情况是,“一个点a处在某个scc中,另一个点b搜索到a点时a已经弹栈”,出现这种情况说明b点不会处在a所在的scc中,用a点数据更新b点是错误的,因此需要加入in_stk的判断
但是在无向图中,假设存在一种情况是“一个点a处在某个e-dcc中,另一个点b搜索到a点时a已经弹栈”,由此构造出下图,由于是无向边,在b搜索到a之前a已经将b搜索过了,同时边双连通分量过程是不允许一条边走两次的,因此b走到a的路径是非法路径(这是因为无向图中不存在横叉边),也就是说上述假设情况是无法发生的,因此在搜索到一个已经被搜索过的点时,无需判断其是否处在栈中
割点
割点的判定同样利用\(dfn\)和\(low\)两个标记,对于点x,其是割点有以下情况
- x不是根节点(root) && x有儿子y && \(low[y] >= dfn[x]\)
- x是根节点 && 在深度搜索树中x有2个以上的儿子
注:情况2中给定的条件是“在深度搜索树中有2个以上儿子”,这不同于在图上x有2个以上儿子,例如右图,根节点的确有2个儿子A和B,但A和B之间的连接使得root节点并非割点
无向图转边双连通分量最少加边数
例题引入
结论
按照类似有向图强连通分量缩点的思想,使用Tarjan将图中边双连通分量进行缩点,设缩点后叶子节点数量为\(cnt\)
注:叶子节点是指度数为1的点
则\(最少加边数 = \lceil \frac{cnt}{2} \rceil = \lfloor \frac{cnt + 1}{2} \rfloor\)
该结论的证明还暂时没有掌握,感性的理解是如果\(cnt\)为偶数,那么叶子节点两两连边从而与根节点形成环路保证其称为边双连通分量;如果\(cnt\)为奇数,那么前偶数个叶子节点实行之前的操作,最后一个节点直接连向根节点
算法流程
- 将边双连通分量进行缩点
- 统计各边双连通分量度数
- 计算叶子节点个数并计算出答案