对于连通图G,如果其全部顶点和一部分边构成一个子图,若这一部分边刚好是图中所有顶点连通,且又不形成回路,则称子图G1是原图G的一颗生成树。
对于同一个图,可以有多个不同的生成树,例如下图,是一个带权的无向图,当然它的生成树不知这两种:
由上图可以看出生成树是将原图的全部顶点以最小的边连通的子图,对于有n个顶点的连通图,生成树有n-1条边,若边数小于此数就不可能将各顶点连通,如果边的数量多于n-1,条边,必定会产生回路。
对于一个带权连通图,生成树不同,树中各边上权值总和也不同,权值最小的生成树成为图的最小生成树。
求图的最小生成树在很多领域都有实用价值,例如再用一个图表示城市之间的交通系统,每一个顶点代表一个城市,边的权值表示两城市间的距离,当有多个城市时,可能会有n*(n+1)/2条线路,怎样怎样选择n-1条线路,使各个城市之间总距离最短?可以用最小生成树解决。
下面介绍Prim算法构造最小生成树:
假设图中所有顶点构成一个名为V的集合,最小生成树最终也将具有该集合中所有顶点,另外再设计一个集U,保存最小生成树中的顶点,初始时该集合为空,首先从V集合中取出一个顶点,设为V0,将其加入到U集合中,从V0的邻接点中选择点Vn,使(V0,Vn)边的权值最小,得到最小生成树中一条边,将Vn点加入到U集合中。
接着从V~U集合(即未在U集合中的其他顶点)再选出一个与V0,Vn邻接的顶点(未在U集合中的顶点),找出权值最小边,得到最小生成树的另一边。
按照这个步骤不断重复,最后即可得到最小生成树。
实现Prim算法,需要使用两个辅助数组,tmapvertex和weight,这两个数组长度和顶点数量相同,数组作用如下:
- 数组tmpvertex在对应位置保存邻接顶点信息,例如,若tmpvertex[1]中顶点V1表示顶点V1与序号为2的顶点(数组序号从0开始,所以tmpvetex[1]中的1加上1,就是2)之间有一条边,每个元素表示一条邻接边,若无邻接边,则设置对应元素的值为-1.
- 数组weight保存tempvertex对应邻接边的权值
0 | 1 | 2 |