最小树形图
最小树形图是在一个有向图中,找到一颗有向树使得边权和最小。
首先问题是为什么不能直接用kruskal或prim来做。考虑这个例子:
由于\(1\to 3,1\to 2\)的边权是一样的,所以都有可能被第一次选到,而如果选了\(1\to 3\),那么很明显是错误的。但是如果是无向图就不会有这个问题。
所以对于有向图最小生成树,即最小树形图,我们可以使用\(O(VE)\)的朱刘算法,是由朱永津和刘振宏在1965年提出的。
首先,很显然的是,如果图不连通,那么最小树形图是不存在的,否则一定是存在的。
接下来考虑如何求最小树形图。算法步骤如下:
- dfs找出当前图中每个点的最小入边\(in[v]\)
- 如果当前的所有最小入边不构成环,那么这就是当前图的最小树形图,答案累加所有边权并返回。
- 否则先把答案累加环中的边权,再进行缩环。
- 把环缩成一个点,设这个点为\(k\),那么原来环中点到\(v\)的出边,其中边权最小为\(w\),那么新边为\((k,v,w)\)
- 对于环中点的入边\((u,v,w)\),新边为\((u,k,min(w-in[v]))\)
- 重复上面的步骤
其中缩环的第二种情况的意义是,下一次求出到这个环中的边时,可以把对应的那条之前环中的边断掉。