最小生成树

忘是亡心i 2022-08-03 05:28 331阅读 0赞

一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。

最小生成树在n个顶点的情形下,有n-1条边。生成树是对连通图而言的,是连同图的极小连通子图,包含图中的所有顶点,有且仅有n-1条边。非连通图的生成树则组成一个生成森林;若图中有n个顶点,m个连通分量,则生成森林中有n-m条边。

  1. #include "stdafx.h"
  2. #include<vector>
  3. #include<algorithm>
  4. using namespace std;
  5. #define N 9
  6. #define MIN 1000000
  7. typedef struct{
  8. int vexnum, arcnum;
  9. char vexs[N];
  10. int matirx[N][N];
  11. }graph;
  12. graph g;
  13. int mx[N][N];
  14. // 初始化图数据
  15. // 0---1---2---3---4---5---6---7---8---
  16. // A---B---C---D---E---F---G---H---I---
  17. void initiate_graph()
  18. {
  19. // A-B, A-D, A-E
  20. g.matirx[0][1] = 10;
  21. g.matirx[1][0] = 10;
  22. g.matirx[0][3] = 5;
  23. g.matirx[3][0] = 5;
  24. g.matirx[0][4] = 7;
  25. g.matirx[4][0] = 7;
  26. // B-C
  27. g.matirx[1][2] = 18;
  28. g.matirx[2][1] = 18;
  29. // C-F
  30. g.matirx[2][5] = 3;
  31. g.matirx[5][2] = 3;
  32. // D-E, D-G
  33. g.matirx[3][4] = 9;
  34. g.matirx[4][3] = 9;
  35. g.matirx[3][6] = 25;
  36. g.matirx[6][3] = 25;
  37. // E-F, E-H
  38. g.matirx[4][5] = 1;
  39. g.matirx[5][4] = 1;
  40. g.matirx[4][7] = 14;
  41. g.matirx[7][4] = 14;
  42. // F-H, F-I
  43. g.matirx[5][7] = 8;
  44. g.matirx[7][5] = 8;
  45. g.matirx[5][8] = 30;
  46. g.matirx[8][5] = 30;
  47. // G-H
  48. g.matirx[6][7] = 6;
  49. g.matirx[7][6] = 6;
  50. // H-I
  51. g.matirx[7][8] = 20;
  52. g.matirx[8][7] = 20;
  53. }
  54. bool UDless(pair<pair<int, int>,int> elem1, pair<pair<int, int>,int> elem2)
  55. {
  56. return elem1.second < elem2.second;
  57. }
  58. //广度优先遍历一遍,如果不能经过所有节点,则不是连通图
  59. bool IsConnectedGraph()
  60. {
  61. int a[N] = { 0 };
  62. vector<int>vec;
  63. vector<int>aa;
  64. int k = 0;
  65. vec.push_back(0);
  66. a[0] = 1;
  67. while (vec.size() != 0)
  68. {
  69. while (k < vec.size())
  70. {
  71. int mm = 0;
  72. while (mm < N)
  73. {
  74. if (mx[vec[k]][mm]>0 && a[mm]==0)
  75. {
  76. aa.push_back(mm);
  77. a[mm] = 1;
  78. }
  79. mm++;
  80. }
  81. k++;
  82. }
  83. vec = aa;
  84. k = 0;
  85. aa.clear();
  86. }
  87. for (int i = 0; i < N; i++)
  88. if (a[i] == 0)
  89. return false;
  90. return true;
  91. }
  92. bool is_erasable(int ii,int jj)
  93. {
  94. mx[ii][jj] = 0;
  95. mx[jj][ii] = 0;
  96. if (IsConnectedGraph())
  97. return true;
  98. else
  99. return false;
  100. }
  101. void MST(graph g)
  102. {
  103. int sv = 0;
  104. vector<pair<pair<int, int>, int>>ve;
  105. for (int i = 0; i < N; i++)
  106. for (int j = i; j < N; j++)
  107. {
  108. if (g.matirx[i][j])
  109. {
  110. sv++;
  111. pair<int, int > aa = make_pair(i, j);
  112. pair<pair<int, int>, int>a = make_pair(aa, g.matirx[i][j]);
  113. ve.push_back(a);
  114. }
  115. }
  116. for (int i = 0; i < N; i++)
  117. for (int j = 0; j < N; j++)
  118. {
  119. mx[i][j] = g.matirx[i][j];
  120. }
  121. int k = sv - N + 1;
  122. sort(ve.begin(), ve.end(),UDless);
  123. while (k > 0)
  124. {
  125. pair<pair<int, int>, int>a = ve.back();
  126. ve.pop_back();
  127. while (!is_erasable(a.first.first, a.first.second))
  128. {
  129. mx[a.first.first][a.first.second] = a.second;
  130. mx[a.first.second][a.first.first] = a.second;
  131. a = ve.back();
  132. ve.pop_back();
  133. }
  134. k--;
  135. }
  136. }
  137. int _tmain(int argc, _TCHAR* argv[])
  138. {
  139. initiate_graph();
  140. MST(g);
  141. system("pause");
  142. return 0;
  143. }

发表评论

表情:
评论列表 (有 0 条评论,331人围观)

还没有评论,来说两句吧...

相关阅读

    相关 生成

    最小生成树定义: 在一给定的无向图 G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边(即![(u, v)\\in E][u_ v_in E]),而

    相关 生成

    一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。 最小生成树在n个顶点的情形下,有n-1条边。生成树是对连

    相关 生成

    有n个城市,m条道路,现在输入n到m的道路的长度,用最少的边将图连接,输出让图连接的最小值 这道题我研究了好长时间才把答案看明白,现在给大家分享一下 具体代码如下

    相关 生成

    问题提出: 要在n个城市间建立通信联络网。顶点:表示城市,权:城市间通信线路的花费代价。希望此通信网花费代价最小。 问题分析: 答案只能从生成树中找,因为要做到任何

    相关 生成

    kruskal算法基本思路:先对边按权重从小到大排序,先选取权重最小的一条边,如果该边的两个节点均为不同的分量,则加入到最小生成树,否则计算下一条边,直到遍历完所有的边。 p

    相关 生成

    最小生成树 什么是最小生成树 给定一张无向带权图G=(V,E,W),从中挑选出|V|-1条边,使得V中任意两点都有直接或者间接的路径 显然,最后得到的子