最小生成树的两种算法 — Prim & Kruscal
什么是最小生成树
最小生成树是一副连通加权无向图中一棵权值最小的生成树。
在一给定的无向图 G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边(即 {\displaystyle (u,v)\in E}(u,v)\in E),而 w(u, v) 代表此边的权重,若存在 T 为 E 的子集且 (V, T) 为树,使得 w(T) 最小,则此 T 为 G 的最小生成树。
最小生成树 — Prim 算法
算法描述
- 准备:定义一个二维数组 dist 来存储每两个点之间的距离,定义一个一维数组 minc 来存储每个点到已经在最小生成树中的点的最小距离
- 初始化邻接矩阵,然后通过输入的数据来改变邻接矩阵
- 选择一个顶点 s 作为最小生成树中的点,初始化 minc 数组,其中 minc[s] 为 0 ,若其他点到 s 有边,则初始化为边的权重,否则初始化为 MAX 值
- 选择 minc 数组中不为 0 且最小的一个值对应的点,加入最小生成树,将该值变为 0,更新其他点到最小生成树中的点的最小距离
- 重复第三步操作直到所有的点都加入到最小生成树中
代码示例
1 | #include <stdio.h> |
最小生成树 — kruscal 算法
算法描述
- 准备:并查集的知识
- 用邻接链表存储每一条边,再用一个结构数组存储所有的边,将结构数组按照边的权值大小从小到大排序
- 遍历结构数组,如果一条边的两个端点的祖宗不同,则将起点的祖宗的祖宗设为终点的祖宗(有点绕嘴),否则直接跳到下一条边
- 重复 2 操作,直到所有的点都加入到了最小生成树中
代码示例
1 | #include <stdio.h> |
注意事项
Prim 算法多用于稠密图,Kruscal 算法多用于稀疏图