首页 > 其他 > 详细

公路通

时间:2020-11-22 13:05:39      阅读:24      评论:0      收藏:0      [点我收藏+]
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef struct
 4 {
 5     int a,b;
 6     int price=99999;
 7 }lu;
 8 bool cmp(lu a,lu b)
 9 {
10     return a.price<b.price;
11 }
12 lu a[3001];
13 int   p[1001];
14 int main()
15 {
16     int n,m;
17     int fei=0;
18     int num=0;//记录加入的边数
19     scanf("%d%d",&n,&m);
20     for(int i=1;i<=m;i++)
21     {
22         cin>>a[i].a>>a[i].b>>a[i].price;
23     }
24     for(int i=1;i<=n;i++)
25     {
26         p[i]=i;//每个点先赋值一个初始集合
27     }
28     sort(a+1,a+m,cmp);
29     for(int i=1;i<=m;i++)
30     {
31         if(p[a[i].a]!=p[a[i].b])//这条边的两个端点还不属于一个集合
32         {
33             num++;//已经加入的边数++
34             fei+=a[i].price;//价钱++
35             int z=p[a[i].b];
36             for(int j=1;j<=n;j++)
37             {
38                 if(p[j]==z)
39                 {
40                     p[j]=p[a[i].a];//找出之前已经同化的所有顶点并且让他重新同化
41                 }
42             }
43             if(num==n-1)
44                 break;
45         }
46     }
47     if(num==n-1)
48         cout<<fei;
49     else if(num<n-1)
50     {
51         cout<<"-1";
52     }
53 }

之前自己第一次做的时候,想不出来究竟如何来判断是否构成回路,因此卡在这里,看了huo的代码,他是用集合来记录点的集合,而我之前是记录边是否被用过,这样的话,点被用过的话,将已经用的点全部归于一个集合,比如第一个边被用了之后,这个边的y的集合要等于这个边的x,然后后面依次找,因为每次找的时候,有可能新边的其中一个点之前同化过其他的点,所以,要进行一次循环查找,把之前同化的点也变成新的这个边的x的集合

公路通

原文:https://www.cnblogs.com/lhy-home/p/14018509.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!