Kruskal算法C++

 
  1. #include<iostream>
  2. using namespace std;
  3. const int n=6; //图的顶点数
  4. const int e=10; //图的边数 n-1=<e<=n(n-1)/2 
  5. typedef int adjmatrix[n][n]; 
  6. typedef struct//生成树的边结点
  7. int fromvex,endvex; //边的起点与终点
  8. int weight; //边上的权
  9. }TreeEdgeNode;
  10. typedef TreeEdgeNode edgesetT[n-1]; //这是不
  11. typedef TreeEdgeNode edgesetG[e]; 
  12. void Kruskal(edgesetG GE,edgesetT CT,int n)
  13. //利用克鲁斯卡尔算法求边集数组GE所示图的最小生成树,
  14. //树中每条边依次存于数组C中
  15. {
  16. int i,j;
  17. adjmatrix s;//用二维数组s作为集合使用,其中每一行元素
  18. //s[i][0]~s[i][n-1]用来表示一个集合,若s[i][t]==1
  19. //则表示v[t]顶点属于该集合,否则不属于s[i]集合
  20. for(i=0;i<n;i++)
  21. //初始化s集合,使每一个顶点分属于不同的集合 
  22. for(j=0;j<n;j++)
  23. if(i==j)
  24. s[i][j]=1;
  25. else
  26. s[i][j]=0;
  27. }//循环执行结束后,使得v[i]顶点属于s[i]集合中
  28. int k=1;//k表示待获取的最小生成树中的边数,初值为1
  29. int d=0;//d表示GE中待扫描边元素的下标位置,初值为0
  30. int m1,m2;//m1和m2用来分别记录一条边的两个顶点所在的集合的序号
  31. while(k<n)
  32. {//进行n-1次循环,得到最小生成树中的n-1条边
  33. /*for(i=0;i<n;i++)
  34. {//求出边GE[d]的两个顶点所在集合的序号m1和m2]
  35. for(j=0;j<n;j++)
  36. {
  37. if(GE[d].fromvex==j&&s[i][j]==1)//找起点
  38. m1=i;
  39. if(GE[d].endvex==j&&s[i][j]==1)//找终点
  40. m2=i;
  41. }*/
  42. //可以把上面的重for循环改良成如下的一重for循环
  43. for(i=0;i<n;i++)
  44. {
  45. if(s[i][GE[d].fromvex]==1)//找起点
  46. m1=i;
  47. if(s[i][GE[d].endvex]==1)//找终点
  48. m2=i;
  49. }
  50. if(m1!=m2)
  51. //若两集合序号不等,则表明GE[d]是生成树中的一条边,
  52. //应将它加入到数组C中
  53. CT[k-1]=GE[d];
  54. //cout<<"CT[<<k-1<<]=<<CT[k-1].
  55. k++;
  56. for(j=0;j<n;j++)
  57. {//合并两个集合,并将另一个置为空集
  58. s[m1][j]=s[m1][j]||s[m2][j];
  59. s[m2][j]=0;
  60. }
  61. }
  62. d++;//d后移一个位置,以便扫描GE中的下一条边
  63. }
  64. void main()
  65. {
  66. int i;
  67. edgesetG GE;
  68. edgesetT CT;
  69. cout<<"请按权值小到大输入边集:"<<endl;
  70. for(i=0;i<e;i++)//这是不妥的,因为不知道到底有多少边
  71. {
  72. cin>>GE[i].fromvex>>GE[i].endvex>>GE[i].weight;
  73. }
  74. Kruskal(GE,CT,n);
  75. cout<<"最上生成树的边集为:"<<endl;
  76. for(i=0;i<n-1;i++)
  77. {
  78. cout<<CT[i].fromvex<<" "<<CT[i].endvex<<" "<<CT[i].weight<<endl;
  79. }
  80. /*测试用例一:
  81. 请按权值小到大输入边集:
  82. 0 4 4
  83. 1 2 5
  84. 1 3 8
  85. 2 3 10
  86. 1 5 12
  87. 3 5 15
  88. 0 1 18
  89. 3 4 20
  90. 0 5 23
  91. 4 5 25
  92. 最上生成树的边集为:
  93. 0 4 4
  94. 1 2 5
  95. 1 3 8
  96. 1 5 12
  97. 0 1 18
  98. */
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值