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