1. 程式人生 > >HDU - 1863 暢通工程

HDU - 1863 暢通工程

圖片 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)//
權值排序 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);//此處就是將給的權值先排序 29
for(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 }
View Code

HDU - 1863 暢通工程