HDU1863_暢通project【Prim】【並查集】
阿新 • • 發佈:2017-05-25
計數 道路 不足 rim scanf article ava 能夠 else
暢通project
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 17867 Accepted Submission(s): 7552
Problem Description
省政府“暢通project”的目標是使全省不論什麽兩個村莊間都能夠實現公路交通(但不一定有直接的公路相連,僅僅要能間接通過公路可達就可以)。
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 17867 Accepted Submission(s): 7552
Problem Description
省政府“暢通project”的目標是使全省不論什麽兩個村莊間都能夠實現公路交通(但不一定有直接的公路相連,僅僅要能間接通過公路可達就可以)。
經過調查評估,得到的統計表中列出了有可能建設公路的若幹條道路的成本。現請你編敲代碼,計算出全省暢通須要的最低成本。
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
?
Source
浙大計算機研究生復試上機考試-2007年
題目大意:給你M個村莊、N條路,即N條路所連接的兩個村莊即路程。
問是否能各個村莊都能有路達到,若不通。則輸出‘?‘,若通,則計算出連接
全部村莊最小的路程和
思路:先用並查集推斷是否能全部村莊。
把有路連接的村莊並到一個集合裏。
最後,若僅僅有一個集合。則全部村莊都能連接。若有兩個以上,則肯定有
村莊不能到達。
然後用Prim算法計算出圖的最小生成樹。
#include<stdio.h> #include<string.h> int N,M; int map[110][110],vis[110],low[110]; int father[110]; int find(int a) { if(a != father[a]) father[a] = find(father[a]); return father[a]; } int prim() { int pos,res = 0; memset(vis,0,sizeof(vis)); vis[1] = 1; pos = 1; for(int i = 1; i <= M; i++) if(i != pos) low[i] = map[pos][i]; for(int i = 1; i < M; i++) { int Min = 0xffffff0; for(int j = 1; j <= M; j++) { if(vis[j] == 0 && Min > low[j]) { Min = low[j]; pos = j; } } res += Min; vis[pos] = 1; for(int j = 1; j <= M; j++) { if(vis[j] == 0 && low[j] > map[pos][j]) low[j] = map[pos][j]; } } return res; } int main() { int posi,posj,cost; while(~scanf("%d%d",&N,&M) && N!=0) { for(int i = 1; i <= M; i++) father[i] = i; for(int i = 1; i <= M; i++) { for(int j = 1; j <= M; j++) { map[i][j] = 0xffffff0; } } while(N--) { scanf("%d%d%d",&posi,&posj,&cost); map[posi][posj] = map[posj][posi] = cost; int a = find(posi); int b = find(posj); if(a != b) { father[b] = a; } } int a = find(1); int flag = 1; for(int i = 2; i <= M; i++) { if(find(i)!=a) { flag = 0; } } if(flag == 0) printf("?\n"); else { int ans = prim(); printf("%d\n",ans); } } return 0; }
HDU1863_暢通project【Prim】【並查集】