Kruskal算法
Kruskal算法
时间复杂度:
- O(mlogm)
使用范围
- 求朴素最小生成树
- 求最小生成森林,(求最小生成树的前一半)
- 已知一些边,求最小生成树(求最小生成树的后一半)
具体实现:
- 将所有边按照权重从小到大排序
- 枚举每条边的顶点a, b, 权重c,若a, b不在一个集合,则合并a, b集合, 反之则跳过,判断下一条边
算法证明:
- 证明思路与prim算法类似。
- 如何证明这条边一定可以被选?
- 假设不选当前边,最终得到了一棵树。然后将这条边加上,那么必然会形成一个环,在这个环上,一定可以找出一条长度不小于当前边的边,那么把当前边替换上去,结果一定不会变差。
- 证明结论:若该边的两点所在的集合不同,则该边必定在最小生成树中
- 证明结论如下:
- 反证法:假设没有选择该边x1,则必定选择了之后的边x2使得两集合合并,使之形成最小生成树
- 证明:把边x1加到用x2形成的最小生成树中,则会在形成一个环,且该边一定包含x1,x2,此时若把x2去除,则形成的也为一个生成树,且因为x1小于x2,新生成的生成树比原来的权值和还小,则可证x1比x2更合适,所以得证,若上述证明结论的情况发生,则必定成立!
代码如下:
1 | struct Edge |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Moench 的算法宝库!