让一棵树向外生长
在连通无向带权图中,先任选一个顶点加入树。树内与树外顶点形成一个割,每次取跨越这个割的最轻边,把相应外部顶点接入;不断重复,直到覆盖全部顶点。
候选必须跨越当前边界。两个端点都已经在树内的轻边,不会带来新顶点,还会造成环,不能因权重低就加入。两个端点都在树外的边,也不是当前这棵树下一步接入所需的边。
参考:[1]
惰性边队列与主动更新
惰性实现把新顶点通向树外的边加入优先队列。树扩大后,旧候选的另一个端点也可能已在树内,这些失效边暂时保留,等它们弹出时再检查并跳过;因此队列里不一定始终只有当前有效跨割边。
主动更新的实现只为每个尚未加入的候选顶点保留连接当前树的最轻边。新顶点接入时检查其邻边,若提供更便宜的连接便降低对应优先级;这需要能够按顶点定位并更新条目的索引优先队列。
参考:[1]
实现边界不等于最短路径条件
在连通图上,使用二叉堆的常见惰性版本最坏需要O(E log E)时间和O(E)额外空间;索引二叉堆的主动版本可用O(E log V)时间和O(V)额外空间,均不计原图存储。两种写法遵守同一个安全接边原则,队列中保存的对象却不同。 对一般断开图,还须计入遍历和初始化全部V个顶点的成本;惰性实现的额外空间应包含顶点状态,记为O(V+E),不能因没有边便忽略孤立顶点。
最小生成树只依赖边权次序的相关性质,可以处理负权,不能把Dijkstra最短路常用的非负权条件直接套过来。断开图需从其他尚未覆盖的分量重新启动生长,结果才是完整的最小生成森林;一次局部生长不会越过不存在的边。