当前位置:   article > 正文

7-3 最小生成树的唯一性(Kruskal)

最小生成树的唯一性

因为我们要学习算法的多样性,所以我们这道题采取更为简单的算法Kruskal具体代码讲解如下

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef struct Edge
  4. {
  5. int x,y,z;
  6. }op;//定义输入方便的结构体x为起点,y为终点,z为权值
  7. bool cmp(op a,op b)
  8. {
  9. return a.z<b.z;//以小为排序规则
  10. }
  11. int p[1000]; //并查集数组
  12. int find(int x)//并查集
  13. {
  14. if(p[x]!=x)p[x]=find(p[x]);
  15. return p[x];
  16. }
  17. set<int>hi;//为的是找出对应集合
  18. int main()
  19. {
  20. int a,b;cin>>a>>b;
  21. for(int i=1;i<=a;i++)p[i]=i;//并查集始初化
  22. op mp[250000];//定义的大一点容易溢出
  23. int gp[1000];//这个是为了储存结点的距离方便之后减去操作
  24. int vist[1000];//是否用过该边的一个判断数组
  25. for(int i=0;i<b;i++)vist[i]=0;//始初化
  26. int sum=0;
  27. int cot=0;
  28. for(int i=0;i<b;i++)
  29. {
  30. cin>>mp[i].x>>mp[i].y>>mp[i].z;//输入对应权值和出发起始点
  31. }
  32. sort(mp,mp+b,cmp);//排序
  33. for(int i=0;i<b;i++)//开始算法
  34. {
  35. int as=find(mp[i].x);//找到祖宗
  36. int ad=find(mp[i].y);//找到祖宗
  37. if(as!=ad)//不是一个祖宗构不成环
  38. {
  39. p[as]=ad;//组成一个环
  40. cot++;//边数加1
  41. sum+=mp[i].z;//总距离加起来
  42. vist[i]=1;//该边使用过
  43. gp[mp[i].x]=gp[mp[i].y]=mp[i].z;//保存对应边值
  44. }
  45. }
  46. if(cot<a-1)//如果边数使用太少则不能全部相连
  47. {
  48. for(int i=1;i<=a;i++)
  49. {
  50. hi.insert(find(i));//插入每一个的祖宗
  51. }
  52. cout<<"No MST"<<endl;
  53. cout<<hi.size();//输出祖宗数量,即集合树数
  54. return 0;
  55. }
  56. cout<<sum<<endl;//反之则可以构成最小树
  57. for(int i=0;i<b;i++)
  58. {
  59. if(!vist[i])//如果该边没用过则交换去除一个边加上可以替代的另一个边
  60. {
  61. int as=mp[i].x;
  62. int ad=mp[i].y;
  63. int res=mp[i].z;
  64. if(sum-gp[as]+res==sum)//如果成功被替代则不是唯一
  65. {
  66. cout<<"No";
  67. return 0;
  68. }
  69. }
  70. }
  71. cout<<"Yes";//反之则是唯一
  72. }

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

闽ICP备14008679号