最小生成树

Kruskal

最常用且大部分情况下效率最高的最小生成树算法

将边按长度从小到大排序每次贪心选择最短的一条边若这条边连接的两个点还为连通则将两个点所在的连通块用这条边连接连通块用并查集维护

证明: 使用归纳法证明任何时候 Kruskal 算法选择的边集都被某棵 MST 所包含
基础: 对于算法刚开始时显然成立最小生成树存在
归纳: 假设某时刻成立当前边集为 $F$$T$ 为这棵 MST考虑下一条加入的边 $e$
如果 $e$ 属于 $T$那么成立
否则$T+e$ 一定存在一个环考虑这个环上不属于 $F$ 的另一条边 $f$ ( 一定只有一条
首先$f$ 的权值一定不会比 $e$不然 $f$ 会在 $e$ 之前被选取
然后 $f$ 的权值一定不会比 $e$不然 $T+e-f$ 就是一棵比 $T$ 还优的生成树了
所以 $T+e-f$ 包含了 $F$并且也是一棵最小生成树归纳成立

时间复杂度 $\Theta(m\log m)$

Kruskal 重构树

这是 Kruskal 算法除了求最小生成树以外的一个重要应用

在使用 $\rm kruskal$ 最小生成树算法的时候会从小到大加入 $n-1$ 条边现在仍按照这个顺序每次加入一条边时将其变成一个点权等于边权的点然后把它作为所连接两个连通块的父亲节点

不难发现两个结点在 MST 上的最短路径上的边权最大值为它们在 $\rm kruskal$ 重构树上 $\rm LCA$ 的点权并且从一个点 $u$ 出发只经过边权小于某值的边能够到达的点集为 $\rm Kruskal$ 重构树上某点的子树内所有的叶子结点

Prim

在稠密图上复杂度最优的最小生成树算法

与 Dijkstra 算法类似选择一个点作为起点每次选择到当前已选的点集中任意一个点距离最短的未选择的点并向其连边再递归操作

证明: 还是说明在每一步都存在一棵最小生成树包含已选边集
基础: 只有一个结点的时候显然成立
归纳: 如果某一步成立当前边集为 $F$, 属于 $T$ 这棵 MST接下来要加入边 $e$
如果 $e$ 属于 $T$那么成立
否则考虑 $T+e$ 中环上另一条可以加入当前边集的边 $f$
首先$f$ 的权值一定不小于 $e$ 的权值否则就会选择 $f$ 而不是 $e$
然后$f$ 的权值一定不大于 $e$ 的权值否则 $T+e-f$ 就是一棵更小的生成树了
因此$e$$f$ 的权值相等, $T+e-f$ 也是一棵最小生成树且包含了 $F$

时间复杂度 $\Theta[(n+m)\log n]$

Boruvka

在大多数完全图上求最小生成树所使用的算法

  • 每次遍历所有的点求出它当前属于哪个连通块

  • 遍历所有的边 $u-v$如果 $u$$v$ 不在同一个连通块就分别用 $u$$v$ 去更新它们所在连通块的最小出边

  • 将每个连通块的最小出边加入 MST 的边集

由于每次连通块数量减半所以时间复杂度 $\Theta(m\log n)$