畅通工程 HDOJ--1863
畅通工程
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 13266 Accepted Submission(s): 5434
Problem Description
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。
Input
测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 N
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从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
1 #include<stdio.h> 2 #include<string.h> 3 int father[105],depth[105]; 4 int dist[105],map[101][101]; 5 int vis[105],n; 6 void init_B() 7 { 8 int i; 9 for(i = 1;i <= n;i ++) 10 { 11 father[i] = i; 12 depth[i] = 0; 13 } 14 } 15 16 int find(int x) 17 { 18 if(x == father[x]) 19 return x; 20 return father[x] = find(father[x]); 21 } 22 23 void unit(int x,int y) 24 { 25 x = find(x); 26 y = find(y); 27 if(x == y) 28 return ; 29 if(depth[x] < depth[y]) 30 father[x] = y; 31 else 32 { 33 if(depth[x] > depth[y]) 34 father[y] = x; 35 else 36 { 37 father[x] = y; 38 depth[y]++; 39 } 40 } 41 } 42 43 void init() 44 { 45 int i; 46 memset(vis,0,sizeof(vis)); 47 for(i = 1;i <= n;i ++) 48 dist[i] = map[1][i]; 49 } 50 51 int main() 52 { 53 int m,i,j,k,a,b; 54 int min,cnt,cost,sum; 55 while(~scanf("%d%d",&m,&n) && m) 56 { 57 init_B(); 58 sum = cnt = 0; 59 for(i = 1;i <= n;i ++) 60 { 61 for(j = 1;j <= n;j ++) 62 { 63 if(i != j) 64 { 65 map[i][j] = 1 << 30; 66 } 67 } 68 } 69 while(m--) 70 { 71 scanf("%d%d%d",&a,&b,&cost); 72 map[a][b] = map[b][a] = cost; 73 unit(a,b); 74 } 75 init(); 76 for(i = 1;i <= n;i ++) 77 { 78 if(i == find(i)) 79 cnt++; 80 if(cnt == 2) 81 break ; 82 } 83 if(cnt == 2) 84 { 85 printf("?\n"); 86 continue ; 87 } 88 for(i = 0;i < n;i ++) 89 { 90 min = 1 << 30; 91 for(j = 1;j <= n;j ++) 92 { 93 if(!vis[j] && min > dist[j]) 94 { 95 min = dist[j]; 96 k = j; 97 } 98 } 99 vis[k] = 1; 100 if(min != 1 << 30) 101 sum += min; 102 for(j = 1;j <= n;j ++) 103 { 104 if(!vis[j] && dist[j] > map[k][j]) 105 dist[j] = map[k][j]; 106 } 107 } 108 printf("%d\n",sum); 109 } 110 return 0; 111 }
Sample Output
3
?