Skip to content

割点与桥 学习笔记

割点

对于一个无向图,如果把一个点删除后这个图的极大连通分量数增加了,那么这个点就是这个图的割点(又称割顶

过程

如果我们尝试删除每个点,并且判断这个图的连通性,那么复杂度会特别的高。所以要介绍一个常用的算法:Tarjan。

首先,我们上一个图:

很容易的看出割点是 2,而且这个图仅有这一个割点。

首先,我们按照 DFS 序给他打上时间戳(访问的顺序

这些信息被我们保存在一个叫做 dfn ( DFS 序)的数组中。

还需要另外一个数组 low,用它来存储不经过其父亲能到达的最小的时间戳。

例如 low[2] 是 1,low[5]low[6] 是 3。

然后我们开始 DFS,我们判断某个点是否是割点的根据是:对于某个顶点 u,如果存在至少一个顶点 vu 的儿子使得 lowvdfnu,即不能回到祖先,那么 u 点为割点。

此根据惟独不适用于搜索的起始点,其需要特殊考虑:若该点不是割点,则其他路径亦能到达全部结点,因此从起始点只「向下搜了一次即在搜索树内仅有一个子结点。如果在搜索树内有两个及以上的儿子,那么他一定是割点了(设想上图从 2 开始搜索,搜索树内应有两个子结点:3 或 4 及 5 或 6如果只有一个儿子,那么把它删掉,不会有任何的影响。比如下面这个图,此处形成了一个环。

我们在访问 1 的儿子时候,假设先 DFS 到了 2,然后标记用过,然后递归往下,来到了 4,4 又来到了 3,当递归回溯的时候,会发现 3 已经被访问过了,所以不是割点。

更新 low 的伪代码如下:

1if v is a son of u2lowu=min(lowu,lowv)3else4lowu=min(lowu,dfnv)

割边(无重边时)

和割点差不多,叫做桥。

对于一个无向图,如果删掉一条边后图中的连通分量数增加了,则称这条边为桥或者割边。严谨来说,就是:假设有连通图 G={V,E}e 是其中一条边(即 eE如果 Ge 是不连通的,则边 e 是图 G 的一条割边(桥

比如说,下图中,

红色的边就是割边。

过程

和割点差不多,只要改一处:lowv>dfnu 就可以了,而且不需要考虑根节点的问题。

割边是和是不是根节点没关系的,原来我们求割点的时候是指点 v 是不可能不经过父节点 u 为回到祖先节点(包括父节点所以顶点 u 是割点。如果 lowv=dfnu 表示还可以回到父节点,如果顶点 v 不能回到祖先也没有另外一条回到父亲的路,那么 uv 这条边就是割边。

割边(有重边时)

然而,上述无重边时的做法在有重边的无向图上是有问题的。

因为两节点间可能不止有一条边,此时它们都不会是桥。

过程

一种思路是将参数 fa 改为刚刚走过的边的编号(每条边的编号一致)即可,即将「不用父节点更新」改为「不用来时的边更新

另一种更简单的思路是设立一个标记判断是否已有一条边抵达父节点,标记后再访问到父节点时正常更新。

下面代码实现了对可能 有重边 的无向图求割边。