文章目录
问题概述
在图论中,我们会遇到这样一类问题:
在一个图中,定义环为这样的一条路径:
从起点 s t st st出发,经过图上任意数量的顶点且每个顶点至多经过一次,最后回到起点 s t st st的一个回路.
也就是说,在一个环里,除了顶点经过两次,其余的点只经过一次.我们这么定义环的大小:
一个环的大小指的是环回路上所有加权路径的权值和.
如下图,是两个环的例子:

左图可以理解为0->1->2->0,长度为7的环,这是个无向图;
右图可以理解为2->3->4->5->2,长度为2的环,这是个有向图.
显然,无论是有向图还是无向图,对于一个环,其起点可以是环上的任意点,如上图左可以看成是1->2->0->1,右可以看成是3->4->5->2->3,于是环的起点和表示是不确定的,但是环的大小是一定的.因此,我们不关心图上每一个点为起点的环的大小,因为可能不计其数,且有大量重复,我们只想知道: 图上的最小环是多少?
常规解法
假设一个环中有一条 i → j i \to j i→j的边,那么要构造一个相对于当前的 i i i和 j j j的最小环,应该在找一条不包括这条边的 i → j i \to j i→j的最短路,加上这条边,就构成了环,显然,对于任意直接连通的两点都需要找这么一条最短路,这属于单源最短路, D i j k s t r a Dijkstra Dijkstra、 S P F A SPFA SPFA、 B e l l m a n − F o r d Bellman-Ford Bellman−Ford都可以做,具体做法如下:
- 对于两个点 i , j i,j i,j,若存在 i → j i \to j i→j直连的路径 < i , j , w > <i,j,w> <i,j,w>,则将设条路径权值 w w w记录下来,再从图中删去;
- 对于删去 < i , j , w > <i,j,w> <i,j,w>的图,以 i i i为源点跑一遍最短路径算法,得到 d i s [ j ] dis[j] dis[j],再将 < i , j , w > <i,j,w> <i,j,w>加回图中;
- 将 w + d i s [ j ] w + dis[j] w+dis[j]和已求出来的最小环值比较,二者取小值作为新的最小环值;
- 对于每条边,重复1至3,直到所有的边都删去过一次,算法结束.
注意事项: 从图中删去边可以将 < i , j , w > <i,j,w> <i,j,w>改为 < i , j , + ∞ > <i,j,+\infin> <i,j,+∞>,加回图中也是类似,做一个逆向操作.
分析: 对于这样的一个算法思路,时间瓶颈显然是在边的数目上,对于一个存在 E E