1. 程式人生 > 實用技巧 >公路通

公路通

 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的集合