1. 程式人生 > >ACM 暢通工程2

ACM 暢通工程2

span bre cin 編寫 bottom ostream 工程 數組 turn

Problem Description 省政府“暢通工程”的目標是使全省任何兩個村莊間都可以實現公路交通(但不一定有直接的公路相連,只要能間接通過公路可達即可)。經過調查評估,得到的統計表中列出了有可能建設公路的若幹條道路的成本。現請你編寫程序,計算出全省暢通需要的最低成本。

Input 測試輸入包含若幹測試用例。每個測試用例的第1行給出評估的道路條數 N、村莊數目M ( < 100 );隨後的 N
行對應村莊間道路的成本,每行給出一對正整數,分別是兩個村莊的編號,以及此兩村莊間道路的成本(也是正整數)。為簡單起見,村莊從1到M編號。當N為0時,全部輸入結束,相應的結果不要輸出。

Output 對每個測試用例,在1行裏輸出全省暢通需要的最低成本。若統計數據不足以保證暢通,則輸出“?”。

Sample Input 3 3 1 2 1 1 3 2 2 3 4 1 3 2 3 2 0 100

Sample Output 3 ? 題解:統計數據不足以保證暢通--》沒有生成最小生成樹    先把道路信息按照成本從小到大排列,然後用並查集生成最小樹,得到所需的最小成本!
 1 /*
 2     Time: 2017/8/8
 3 */
 4 #include<stdio.h>
 5 #include<iostream>
 6 #include<algorithm>
 7
using namespace std; 8 int parent[105]; 9 struct node{ 10 int a,b,v; 11 }casei[999]; 12 13 //初始化parent數組 14 void init() 15 { 16 for(int i = 0; i < 105;i++) 17 parent[i] = i; 18 } 19 20 //找根節點 21 int find(int n) 22 { 23 if(parent[n] == n) 24 return n; 25 else 26 return
find(parent[n]); 27 } 28 29 // 30 int merge(int a,int b) 31 { 32 a = find(a); 33 b = find(b); 34 if(a != b) 35 { 36 parent[b] = a; 37 return 1; 38 } 39 else 40 return 0; 41 42 43 } 44 45 // 46 bool cmp(node a,node b) 47 { 48 return a.v < b.v; 49 } 50 51 int main() 52 { 53 int n,m; 54 while(cin>>n>>m&&n!=0) 55 { 56 init(); 57 for(int i = 0; i < n; i++) 58 { 59 cin>>casei[i].a>>casei[i].b>>casei[i].v; 60 61 } 62 sort(casei,casei+n,cmp); 63 int sum = 0; 64 int count = 0; 65 int ans = 1; 66 for(int i = 0; i < n; i++) 67 { 68 int p = merge(casei[i].a,casei[i].b); 69 if(p) 70 { 71 sum += casei[i].v; 72 73 } 74 75 } 76 for(int i = 1; i <= m;i++) 77 { 78 if(parent[i] == i) count++; 79 if(count > 1) 80 { 81 ans = 0; 82 break; 83 } 84 } 85 86 if(ans) cout<<sum<<endl; 87 else cout<<"?"<<endl; 88 } 89 90 return 0; 91 }

ACM 暢通工程2