算法 - 图的实例 - 最小生成树 (Minimum Spanning Tree)
本文将介绍最小生成树的基础知识,并用C++实现克鲁斯卡尔算法(Kruskal)和普利姆算法(Prim)。
在查看本文之前,需要一些数据结构和程序语言的基础。
尤其是“矩阵”、“矩阵的压缩(matrix)”、“图(graph)”、“队列(queue)”等的知识。
文章目录
1 最小生成树简述 (Introduction)
-
对图使用不同的遍历方法,可得到不同的生成树;
-
从不同的顶点出发也能得到不通过的生成树。
-
有 n 个顶点的连通且带权的图由 n-1 条边;
-
最小生成树:
- 使用 n-1 条边连接网络中的 n 个顶点;
- 且不能使其产生回路;
- 各条边的权值总和最小。
-
重要结论:
- 当权值各边都不同时,最小生成树一定唯一;
- 当权值部分相同时:
- 邻接矩阵:由于选边顺序固定,则最小生成树唯一;
- 邻接表:由于边链表不唯一,则最小生成树不唯一。
2 克鲁斯卡尔算法 (Kruskal Algorithm)
2.1 算法基本思想 (Basic Idea)
-
(1)构造一个只有原连通带权图顶点的新图,即没有边只有顶点(每个顶点都是一个连通分量);
-
(2)从原连通带权图所有边中选择权值最小的边,如果此边两顶点落在新图中不同的连通分量上,则将此边加入新图,将此边舍去;
-
(3)重复步骤(2),直到所有顶点同时在一个连通分量上。
假设原连通带权图:
根据此思想描述生成过程: