当前位置:   article > 正文

无向连通网的最小生成树_无向连通图

无向连通图
对于一个无向网(即带权无向图),生成树上各边权值之和称作这棵生成树的代价,最小代价生成树是各边权值综合最小的生成树,简称最小生成树。

一个无向连通网的最小生成树也可能不是惟一的,但总代价一定是最小的。构造无向连通网的最小生成树方法可以有多种,下面介绍Prim和Kruskal算法就是构造最小生成树的两种算法。

1.prim算法

prim算法是从连通网中的某一个顶点开始,以此作为生成树的初始状态,然后不断地将网中的其他顶点添加到生成树上,直到最后一个顶点添加到生成树上时得到最小生成树,其具体方法是:

(1).从网中的任一顶点开始,先把该顶点包含在生成树中,此时生成树只有一个顶点。
(2).找出一个端点在生成树中,另一个在生成树外的所有边,并把权值最小的边连同它所关联的另一个顶点添加到生成树中;当有两条及以上具有相同最小权值的边可供选择时,选择其中任意一条都可以。
(3).反复执行(2),直到所有顶点都包含在生成树中时止。
为了实现Prim算法,须设一个辅助数组closedge以记录每次选择的权值最小的边。数组元素closedge[i]对应于序号为i的顶点Vi,它包含两个域adjvex和lowcost.若Vi已在生成树上,则置closedge.lowcost=0;
若顶点Vi不在生成树上,用closedge[i].lowcost存放Vi与生成树上顶点构成的最小代价边的权值,而closedge[i].adjvex存放该边所关联的生成树上的另一顶点的序号。
设有n个顶点的无向连通图以邻接矩阵g存储,从序号为k的顶点Vk开始构造最小生成树,则辅助数组的初始情况为:
closedge[k].lowcost=0;
closedge[k].lowcost=g.adjmatrix[k,i];(i!=k且1<=i<=n)
closedge[k].adjvex=k;(i!=k且1<=i<=n)
然后从数组选出某一个j,它满足closedge[i].lowcost不等于0且是最小的值,将Vj添加到生成树上并修改closedge数组的值。如此不断进行下去,直到
全部的n个顶点都在生成树上,就得到了要求的最小生成树。下面给出Prim算法的形式化描述如下:


  1. #define m 30//m为顶点的个数最大值
  2. #define max 99//max为权上次上限值
  3. void prim(mgraph g,int k,int n)//从顶点Vk出发构造有n个顶点的无向连通网g的最小生成树的Prim
  4. {
  5. int i,j,min,p;
  6. struct{
  7. int adjvex;//定义序号域为整型
  8. int lowcost;//假定权值均为整型数
  9. }closedge[m];//定义辅助数组的基类型为结构体
  10. for(i=1;i<=n;i++)//辅助数组初始化
  11. if(i!=k)
  12. {
  13. closedge[i].adjvex=k;//填边在生成树一端的顶点序号
  14. closedge[i].lowcost=g.adjmatrix[k][i];//填边的权值
  15. }
  16. closedge[k].lowcost=0;//顶点Vk已在生成树中,修改辅助数组
  17. for(i=1;i<n;i++)
  18. {
  19. p=1;
  20. min=max;
  21. for(j=1;j<=n;j++)//选最小权值及对应顶点Vp
  22. if(closedge[j].lowcost!=0&&closedge[j].lowcost<min)
  23. {
  24. min=closedge[j].lowcost;//最小权值记在min
  25. p=j;//把与边相关的生成树外的顶点序号记在p中
  26. }
  27. printf("%d %d %d\n",closedge[p].adjvex,p,min);//输出最小边及权值
  28. closedge[p].lowcost=0;//将顶点Vp加入生成树中
  29. for(j=1;j<=n;j++)//修改辅助数组的相应值,以便下一次选最小权值的边
  30. if(g.adjmatrix[p][j]<closedge[j].lowcost)
  31. {
  32. closedge[j].lowcost=g.adjmatrix[p][j];//修改权值域
  33. closedge[j].adjvex=p;//记下边在生成树一端的顶点序号
  34. }
  35. }//选一条边及对应顶点结束
  36. }

2.Kruskal算法

Kruskal算法是求无向连通网的最小生成树的另一种常用算法。它与prim算法不同,时间复杂度主要是与网中边的数量e相关为O(eloge),适用于求边稀疏的无向连通网的最小生成树。

Kruskal算法的思想为:

(1).将n个顶点看作是n个独立的连通分量,将e条边按权值大小由小到大排序。

(2).从权值最小的边开始依权值递增顺序查看每一条边,如果该边所依附的两个顶点在两个不同的连通分量上,则选定此边连接两个连通分量为一个连通分量,否则舍弃此边。

(3).反复执行(2),直到所有顶点都在同一个连通分量上为止,这个连通分量即所求的最小生成树。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/891161
推荐阅读
相关标签
  

闽ICP备14008679号