采用Prim算法和Kruskal算法构造最小生成树
实验报告
实验名称: 采用Prim算法和Kruskal算法构造最小生成树
1.问题
给定一张边带权的无向图G=(V,E),其中V表示图中点的集合,E表示图中边的集合,n=|V| ,m=|E|。由V中的全部n个顶点和E中n-1条边构成的无向连通子图被称为G的一颗生成树,其中边的权值之和最小的生成树被称为无向图G的最小生成树。
问题:要在n个城市之间铺设光缆,主要目标是要使这 n 个城市的任意两个之间都可以通信,但铺设光缆的费用很高,且各个城市之间铺设光缆的费用不同,因此另一个目标是要使铺设光缆的总费用最低。这就需要找到带权的最小生成树。
用Prim算法和Kruskal算法构造最小生成树。
2.解析
实例问题:要在6个城市(ABCDEF)之间铺设光缆,主要目标是要使这6个城市的任意两个之间都可以通信,但铺设光缆的费用很高,且各个城市之间铺设光缆的费用不同,因此另一个目标是要使铺设光缆的总费用最低。
请找出一条路线,使铺设光缆的总费用最低。
如图:
(1)Prim算法
Prim是一种“贪心”算法,对节点进行操作,每次遍历添加一个点,这时我们就不需要使用并查集了。
具体步骤为:
- 输入:一个加权连通图,其中顶点集合为V,边集合为E;
- 初始化:Vnew={x},其中x为集合V中的任意节点(起始点),Enew={},为空;
- 在集合E中选取权值最小的边<u,v>,其中u为集合Vnew集合当中,并且v属于V(如果如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
- 将v加入集合Vnew中,将<u,v>边加入集合Enew中;
- 重复上两步操作,直到Vnew=V;
- 输出:使用集合Vnew和Enew来描述所得到的最小生成树。
(2)Kruskal算法
- 对所有节点遍历建立并查集,按照边的权重建立最小堆
- 取出最小堆堆顶数据,并判断两端节点是否在同一集合
- 对所有节点遍历建立并查集,按照边的权重建立最小堆如不在,则将这两个节点添加到同一集合,接着将边加入生成边,如在,则不进行操作,为无效边
- 重复上面的操作,直到所有的边都检查完
3.设计
[核心伪代码]
(1)Prim算法
void Prim(