公路通
阿新 • • 發佈:2020-11-22
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;//記錄加入的邊數 19scanf("%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的集合