Kruskal最小生成树问题,小有不同是某些边已存在,初始化找爹数组时应该将其设置,体现在代码24-29行
基本思路可参考:《Kruskal生成最小生成树解决畅通工程问题》
[Kruskal思路]:每次拿出最权值最小的一边,若不构成环则将其选中,否则继续遍历

  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<cstring>
  4. #include<cmath>
  5. #include<iostream>
  6. #include<algorithm>
  7. using namespace std;
  8. const int maxn = 100 + 10;
  9. const int maxn2 = maxn*(maxn-1)/2;
  10. int f[maxn];
  11. struct edge{ // 一条边
  12. int a; // 2端点+1权值+1状态
  13. int b;
  14. int weight;
  15. int status;
  16. }edges[maxn2];
  17. int find(int x){ //找爹
  18. return x==f[x]?x:(find(f[x]));
  19. }
  20. void init(int n,int m){
  21. for(int i=1;i<=n;i++){
  22. f[i]=i;
  23. }
  24. for(int i=0;i<m;i++){
  25. if(edges[i].status==1){ //初始化找爹数组时将已连接的边连接
  26. f[find(edges[i].a)] = find(edges[i].b);
  27. }
  28. }
  29. }
  30. bool cmp(edge e1,edge e2){ //将边数组升序排序
  31. return e1.weight<e2.weight;
  32. }
  33. int main(){
  34. int n;
  35. while(scanf("%d",&n)==1 && n!=0){
  36. int m = n*(n-1)/2;
  37. for(int i=0;i<m;i++){
  38. cin>>edges[i].a>>edges[i].b>>edges[i].weight>>edges[i].status;
  39. }
  40. init(n,m);
  41. sort(edges,edges+m,cmp);
  42. int ans = 0;
  43. for(int i=0;i<m;i++){
  44. if(edges[i].status==1) continue;
  45. int fa = find(edges[i].a); //a的祖先
  46. int fb = find(edges[i].b); //b的祖先
  47. if(fa!=fb){ //不是同一个祖先,相连不会成环
  48. f[fa] = fb; //相连(a的祖先【的祖先】是b的祖先)
  49. ans+=edges[i].weight; //修路加其权值
  50. }
  51. }
  52. cout<<ans<<endl;
  53. }
  54. return 0;
  55. }
点赞(0)
 

9.3 分

3 人评分

 

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论