motivation
最近Leetcode每日一题老是遇到minimum spanning tree的问题, 刚好算法课没有讲到, 就自己学习一下.
我的定义
MST是具有n个结点和权值和最小的n-1条边的联通无环无向图(树)
主要算法
1 Kruskal
CLRS pseudocode:

解释:
- 贪心思想, 每次选取不成环的最小权重边
- 需要用到并查集
- 朴素实现需要用到堆
- 也可以不使用堆, 直接根据权值sort, 然后所有边都UNION.
应用举例: https://leetcode-cn.com/problems/min-cost-to-connect-all-points/ leetcode1584
想象每一对结点之间都有边, 共 C n 2 = n(n - 1)
条边, 选n - 1
条;
1 | class Solution { |
2 Prim
CLRS pseudocode:

同样对上一道leetcode运用prim解法:
1 | class Solution { |
Leetcode 1489 hard 找到最小生成树里的关键边和伪关键边
1489. 找到最小生成树里的关键边和伪关键边 - 力扣(LeetCode) (leetcode-cn.com)
如果从图中删去某条边,会导致最小生成树的权值和增加,那么我们就说它是一条关键边。伪关键边则是可能会出现在某些最小生成树中但不会出现在所有最小生成树中的边。
弄清定义:
- 关键边: 出现在所有MST中, 所以如果一开始我们就把这条边删掉(全程不用这条边), 那么要么生不成MST, 要么生成的MST总代价变大
- 伪关键边: 这条边属于某一个MST, 但不被所有MST共有, 为了确保这条边一定被选中, 我们应该一开始就union这条边.
算法步骤:
- 先计算无任何修改情况下MST的代价cost, 作为后续判断的依据
- 枚举每一条边:
- 判断是不是critical, 如果是, continue
- 判断是不是pseudo critical
1 | class UF { |