当前位置:   article > 正文

C++ 图论-Kruskal算法_kruskal c++

kruskal c++

*最小生成树:

通过的点和边构成的子图,从图的任何一个顶点出发,都可以访问图中所有顶点且代价最小


Kruskal算法求无向图的最小生成树

预备知识:

- 重载运算符

- 并查集


步骤:

1> 按边的权值从小到大排序

2> 按顺序,每次加边,两点已连通则不加

3> 直到有n-1条边

  1. #include <iostream>
  2. #include <algorithm>
  3. using namespace std;
  4. struct Edge { //图的边
  5. int s, t; //起始位置
  6. int w; //权值
  7. bool operator <(const Edge b) const { //C++重载运算符
  8. return w < b.w;
  9. }
  10. };
  11. Edge b[50001]; //不需邻接矩阵 用 struct存边
  12. int n, m;
  13. int father[50001];
  14. int find_f(int x) {
  15. if(father[x] == x) return x;
  16. father[x] = find_f(father[x]);
  17. return father[x];
  18. }
  19. int unite(int x, int y) {
  20. int a = find_f(x);
  21. int b = find_f(y);
  22. if(a == b) return 0;
  23. father[b] = a;
  24. return 1;
  25. }
  26. int Kruskal() {
  27. int x, y;
  28. int num = 0, min_w = 0; //记录边 和 最小生成树的费用
  29. for(int i=1; i<=n; i++) father[i] = i;//初始化并查集
  30. sort(b+1, b+m+1); //已定义'<'运算可以直接用sort
  31. for(int i=1; i<=m; i++) {
  32. x = b[i].s;
  33. y = b[i].t;
  34. if(!unite(x, y)) continue; //两点已经连通
  35. num ++; //边数增加
  36. min_w += b[i].w; //费用增加
  37. if(num == n-1) break;
  38. }
  39. return min_w;
  40. }
  41. void build_graph() { //建图
  42. int x, y, w;
  43. cin >> n >> m;
  44. for(int i=1; i<=m; i++) {
  45. cin >> x >> y >> w;
  46. b[i].s = x;
  47. b[i].t = y;
  48. b[i].w = w;
  49. }
  50. }
  51. int main() {
  52. build_graph();
  53. cout << Kruskal() << endl;
  54. return 0;
  55. }




 


声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号