hdu 1863 畅通工程 (并查集 、 kruskal)
畅通工程
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 37969 Accepted Submission(s): 16915
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 37969 Accepted Submission(s): 16915
Problem Description
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。
Input
测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 N
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 N
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
Output
对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。
对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。
Sample Input
3 3
1 2 1
1 3 2
2 3 4
1 3
2 3 2
0 100
3 3
1 2 1
1 3 2
2 3 4
1 3
2 3 2
0 100
Sample Output
3
?
3
?
C/C++:
1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 #include <stack> 7 #include <set> 8 #include <map> 9 #include <queue> 10 #include <climits> 11 #include <bitset> 12 #define eps 1e-6 13 using namespace std; 14 15 int n, m, my_pre[110]; 16 17 struct node 18 { 19 int a, b, a_b_distance; 20 }my_round[10010]; 21 22 bool cmp(node a, node b) 23 { 24 return a.a_b_distance < b.a_b_distance; 25 } 26 27 int my_find(int x) 28 { 29 int r = x; 30 while (r != my_pre[r]) 31 r = my_pre[r]; 32 int i = x, j; 33 while (r != my_pre[i]) 34 { 35 j = my_pre[i]; 36 my_pre[i] = r; 37 i = j; 38 } 39 return r; 40 } 41 42 void my_join(int a, int b) 43 { 44 int n1 = my_find(a), n2 = my_find(b); 45 if (n1 != n2) 46 my_pre[n1] = n2; 47 } 48 49 int kruskal() 50 { 51 int my_ans = 0; 52 sort(my_round, my_round + n, cmp); 53 for (int i = 0; i < n; ++ i) 54 { 55 if (my_find(my_round[i].a) == my_find(my_round[i].b)) continue; 56 my_join(my_round[i].a, my_round[i].b); 57 my_ans += my_round[i].a_b_distance; 58 } 59 int temp_pre = my_find(1); 60 for (int i = 2; i <= m; ++ i) 61 { 62 if (temp_pre == my_find(i)) continue; 63 return 0; 64 } 65 return my_ans; 66 } 67 68 int main() 69 { 70 ios::sync_with_stdio(false); 71 72 while(scanf("%d%d", &n, &m), n) 73 { 74 /** 75 Initialize 76 */ 77 for (int i = 1; i <= m; ++ i) 78 my_pre[i] = i; 79 memset (my_round, 0, sizeof(my_round)); 80 81 /** 82 Date Input 83 */ 84 for (int i = 0; i < n; ++ i) 85 { 86 scanf("%d%d%d", &my_round[i].a, &my_round[i].b, &my_round[i].a_b_distance); 87 } 88 89 /** 90 Process 91 */ 92 int my_temp = kruskal(); 93 if (my_temp) 94 printf("%d\n", my_temp); 95 else 96 printf("?\n"); 97 } 98 return 0; 99 }