HDU - 1863 暢通工程
阿新 • • 發佈:2018-09-01
圖片 main 個數 play 判斷 class 用例 輸入 code 省政府“暢通工程”的目標是使全省任何兩個村莊間都可以實現公路交通(但不一定有直接的公路相連,只要能間接通過公路可達即可)。經過調查評估,得到的統計表中列出了有可能建設公路的若幹條道路的成本。現請你編寫程序,計算出全省暢通需要的最低成本。
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 ?
就是最小生成樹,我直接用kruskal算法做的,裏面附帶解釋
1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 const int maxn = 1e3; 5 int p[maxn]; 6 int n,m; 7 struct face//存儲數據 8 { 9 int u,v,w; 10 } edge[maxn*maxn]; 11 bool cmp(face a,face b)//View Code權值排序 12 { 13 return a.w<b.w; 14 } 15 void init()//並查集1 16 { 17 for(int i=1; i<=n; i++) 18 p[i]=i; 19 } 20 int find(int x)//並查集2 21 { 22 return x==p[x]?x:p[x] = find(p[x]); 23 } 24 int kruskal()//核心算法 25 { 26 int ans=0; 27 init(); 28 sort(edge,edge+m,cmp);//此處就是將給的權值先排序 29for(int i=0; i<m; i++) 30 { 31 int x = find(edge[i].u); 32 int y = find(edge[i].v); 33 if(x!=y) 34 { 35 ans+=edge[i].w; 36 p[x] = y; 37 } 38 } 39 return ans; 40 } 41 int main() 42 { 43 while(cin>>m>>n&&m)//但是註意輸入,HDU - 1233 和HDU - 1863給的n和m不一樣(切記註意) 44 { 45 for(int i=0; i<m; i++) 46 cin>>edge[i].u>>edge[i].v>>edge[i].w; 47 int sum=0,num=1; 48 int kk=kruskal(); 49 for(int i=1; i<=n; i++)//這個就是判斷根個數!!! 50 { 51 if(p[i]==i) 52 { 53 sum++; 54 } 55 if(sum>1) //如果不加這個循環就可以做“還是暢通工程”,加上這句就是“暢通工程”,都是杭電題。 56 { 57 num=0; 58 break; 59 } 60 } 61 if(num) 62 cout<<kk<<endl; 63 else 64 cout<<‘?‘<<endl; 65 } 66 }
HDU - 1863 暢通工程