1.理论
首先还是要搞清研究对象,简单说最小生成树问题就是找一个无环子集,它既能把所有的节点连接起来,又具有最小的权重。
下面介绍一些定义
切割:无向图G=(V,E)的一个切割(S,V-S)是集合V的一个划分。
如果一条边(u,v) in E的一个端点位于S,另一个端点位于V-S,则称该边横跨切割(S,V-S)。
如果集合A中不存在横跨该切割的边,则称该切割尊重集合A。
在横跨一个切割的所有边中,权重最小的边称为轻量级边。
伪代码:
GENERIC-MST(G,w)
1.A = Empty Set
2.while A does not form a spanning tree
3. find an edge(u,v) that is safe for A
4. A = A U {(u,v)}
5. return A
如果一条边加入到A中,A仍然是某棵最小生成树的子集,就称这样的边为集合A的安全边。
伪代码中涉及到的循环不变式:
1.初始化: 在算法第1行之后,集合A直接满足循环不变式
2.保持: 算法第2到4行通过只加入安全边来维护循环不变式
3.终止: 所有加入到集合A中的边都属于某棵最小生成树,因此算法地行返回的集合A必然是一棵最小生成树。
可以看到整个过程简单明了,最主要的问题还是如何寻找安全边上。下面的定理和推论可以帮助我们。
定理1:设 G = (V,E) 是一个在边E上定义了实数值权重函数w的连通无向图。设集合A为E的一个子集,且A包括在图G的某棵最小生成树中,设(S,V-S)是图G中尊重集合A的任意一个切割,又设(u,v)是横跨切割(S,V-S)的一条轻量级边。那么边(u,v)对于集合A是安全的。
推论1:设 G = (V,E) 是一个连通无向图,并有定义在边集合上的实数值权重函数w。设集合A为E的一个子集,且该子集包