kruskal 和 prim 算法都是求最小生成树经常用到的算法,其中,prim 适用于稠密图(边较多),而 kruskal 更适用于稀疏图(边较少)。其时间复杂度为 O(elog2(e)). 其中,e 为图的边 AD 和 CE 是最短边,长度为 5,AD 是 第一个选择的边,被突出显示。 CE 现在是不构成循环的第二条最短的边,长度为 5,突出显示为第二个边。
下一条边,长度为 6 的 DF,突出显示为第三条边。
接下来的最短边是 AB 和 BE,都是长度为 7. 随机选一条,这里我们选 AB,并且突出显示。边缘 BD 以红色突出显示,因为在 B 和 D 之间已经存在一条路径(绿色),所以如果选择它,它将形成一个循环(ABD)。
继续突出显示下一条最小的边,BE 长度为 7. 许多个边缘以红色显示:BC,因为它会形成回路 BCE。DE,因为它会形成回路 DEBA 和 FE 因为它会形成 FEBAD。
最后,该过程以长度为 9 的边 EG 结束,并找到最小生成树。
kruskal 和 prim 都是基于贪心的思想,其中,kruskal 是每次将属于不同集合的最小的一条边合并。这样,一直合并下去,最终会得到一棵最小生成树(总点数一定,连接的点不断增多,所以未连接的点就会逐渐减少直到为 0),需要注意的是,kruskal 是基于并查集优化的,所以了解 kruskal 算法之前,应该先看一下并查集。
使用结构体储存边的信息:
struct edge{
int a,b; //a为起点,b为终点 int v; //v为该边的权值
}s[maxn];///将结构体按权值排序后,依次进行合并操作
- 并查集合并及路径压缩:
1 | int pre[maxn]; ///各集合 |
复制