最小生成树基本概念
对于一个带权连通无向图 ,生成树是包含全部顶点、且没有回路的连通子图。
若图有 个顶点,则任何生成树都恰好有 条边。生成树中所有边的权值之和称为该生成树的代价;在所有生成树中,代价最小的生成树称为最小生成树(MST)。
任何带权连通无向图都至少存在一棵最小生成树。
最小生成树是否唯一
- 若图中所有边的权值都不相同,则最小生成树唯一;
- 若图中存在权值相同的边,最小生成树不一定不唯一。只有当同权边能够互相替换,并且不改变生成树的总代价时,才可能得到多棵最小生成树。
易错点: 边权互不相同是最小生成树唯一的充分条件,但存在同权边不代表最小生成树一定不唯一。
Prim 算法
基本思想
Prim 算法从一个顶点开始,不断向外扩展。设
其中:
- :已经加入生成树的顶点集合;
- :已经选择的边集合。
初始时任取一个顶点 :
之后,每次从满足 、 的所有边中,选择权值最小的边 ,然后更新:
重复以上过程,直到 。
选择规则
重点:从“树内”到“树外”的所有边中选择权值最小的边。
注意,不是只考察刚刚加入的顶点,而是考察当前整棵树中的所有顶点与外部顶点之间的边。
时间复杂度
书中 Prim 算法的时间复杂度为:
该实现的复杂度与边数 无关,因此尤其适合稠密图。
Kruskal 算法
基本思想
Prim 从某一个顶点开始不断扩张;Kruskal 不从固定顶点出发,而是按照边权从小到大依次选边。
初始时:
此时所有顶点都已存在,但没有边,每个顶点都是一个独立的连通分量。
选择规则
将所有边按权值从小到大排列。每遇到一条边 ,判断 和 是否属于两个不同的连通分量:
- 若属于不同的连通分量,则选择这条边;
- 若已经属于同一个连通分量,则舍弃这条边,因为加入后会形成回路。
一直进行到选出 条边为止。
时间复杂度
书中指出,Kruskal 算法的主要开销是对所有边按照权值排序,因此时间复杂度为:
其主要复杂度由边数 决定,因此特别适合稀疏图。
Prim 与 Kruskal 对比
| 对比 | Prim | Kruskal |
|---|---|---|
| 出发方式 | 从一个顶点开始 | 从所有顶点开始 |
| 每次选择 | 树内到树外的最小边 | 当前权值最小且不成环的边 |
| 观察重点 | 顶点集合 | 边 |
| 是否需要排序全部边 | 不需要 | 需要 |
| 防止成环方式 | 天然不会成环 | 判断两端是否已连通 |
| 时间复杂度 | $O( | V |
| 更适合 | 稠密图 | 稀疏图 |
二者最核心的区别是:
- Prim:从一个点开始,逐渐长成一棵树;
- Kruskal:从很多小树开始,逐渐合并成一棵树。
也可以这样记:
Prim 看“当前树往外怎么长”。
Kruskal 看“下一条最便宜的边能不能加”。
总结
Prim
- 任取一个顶点开始;
- 每次选择树内到树外的最小边;
- 共选择 条边;
- 时间复杂度为 ;
- 适合稠密图。
Kruskal
- 将所有边按权值从小到大排列;
- 选择不会形成回路的边;
- 共选择 条边;
- 时间复杂度为 ;
- 适合稀疏图。