Prim算法
Prim算法
时间复杂度:
- O(n^2 + m)
具体实现:
- 邻接矩阵存边的权值
- 距离初始化为正无穷
- 每次选择当前集合终和外界所连边的权值最小的点
- 将该边所连的点扩展,并用刚扩展的点更新其他点到当前集合的权值
算法证明:
- 证明思路与kruskal算法类似。
- 如何证明这条边一定可以被选?
- 假设不选当前边,最终得到了一棵树。然后将这条边加上,那么必然会形成一个环,在这个环上,一定可以找出一条长度不小于当前边的边,那么把当前边替换上去,结果一定不会变差。
- 证明结论:当前与外界直接相连的权值最小的一条边,这条边一定可以出现在最优解中。
- 证明过程如下:
- 反证法:假设选择最小生成树的某一个状态集合x扩展某一个边x1(最小)时没有选择该边,选择了另一个边x2(非最小),从而形成了一个生成树。
- 证明:已知集合x可扩展多个边x1, x2……x’等(权值升序排列),选择了x2边扩展。若将x1边加入扩展了x2边而最终形成的生成树中,则必定会形成一个环,且该环上一定包含x’这条边,因为x1为扩展出来的权值最小的边,x’等其他边时扩展出来的非权值第一小边,则将x’去掉,x1加上,形成的还是一个生成树,且该生成树的总权值小于原来的生成树。如此,得证。
代码如下:
1 | int prim() |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Moench 的算法宝库!