hdu 1233 还是畅通工程 (prim, kruskal)
还是畅通工程
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 58241 Accepted Submission(s): 26468
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 58241 Accepted Submission(s): 26468
Problem Description
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
Input
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
当N为0时,输入结束,该用例不被处理。
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
当N为0时,输入结束,该用例不被处理。
Output
对每个测试用例,在1行里输出最小的公路总长度。
对每个测试用例,在1行里输出最小的公路总长度。
Sample Input
3
1 2 1
1 3 2
2 3 4
4
1 2 1
1 3 4
1 4 1
2 3 3
2 4 2
3 4 5
0
3
1 2 1
1 3 2
2 3 4
4
1 2 1
1 3 4
1 4 1
2 3 3
2 4 2
3 4 5
0
Sample Output
3
5
3
5
Hint
Hint
Huge input, scanf is recommended.
Hint
Huge input, scanf is recommended.
C/C++(prim):
1 #include <cstdio> 2 #include <climits> 3 using namespace std; 4 5 int n, my_map[110][110]; 6 7 int my_prim() 8 { 9 int my_pos = 1, my_book[110] = {0, 1}, my_dis[110] = {0, INT_MAX}, my_ans = 0; 10 for (int i = 2; i <= n; ++ i) 11 my_dis[i] = my_map[my_pos][i]; 12 for (int i = 1; i < n; ++ i) 13 { 14 int my_temp = INT_MAX; 15 for (int j = 1; j <= n; ++ j) 16 { 17 if (!my_book[j] && my_dis[j] < my_temp) 18 { 19 my_temp = my_dis[j]; 20 my_pos = j; 21 } 22 } 23 my_ans += my_temp; 24 my_book[my_pos] = 1; 25 for (int j = 1; j <= n; ++ j) 26 if (my_dis[j] > my_map[j][my_pos]) 27 my_dis[j] = my_map[j][my_pos]; 28 } 29 return my_ans; 30 } 31 32 int main() 33 { 34 while (scanf("%d", &n), n) 35 { 36 int my_line = n * (n-1) / 2; 37 for (int i = 0; i < my_line; ++ i) 38 { 39 int a, b, a_b_dis; 40 scanf("%d%d%d", &a, &b, &a_b_dis); 41 my_map[a][b] = my_map[b][a] = a_b_dis; 42 } 43 printf("%d\n", my_prim()); 44 } 45 return 0; 46 }
C/C++ (kruskal):
1 #include <cstdio> 2 #include <climits> 3 #include <algorithm> 4 using namespace std; 5 6 int n, my_line, my_pre[110]; 7 struct node 8 { 9 int a, b, a_b_dis; 10 }my_dis[6000]; 11 12 bool cmp(node a, node b) 13 { 14 return a.a_b_dis < b.a_b_dis; 15 } 16 17 int my_find(int x) 18 { 19 int n = x; 20 while (n != my_pre[n]) 21 n = my_pre[n]; 22 int i = x, j; 23 while (my_pre[i] != n) 24 { 25 j = my_pre[i]; 26 my_pre[i] = n; 27 i = j; 28 } 29 return n; 30 } 31 32 void my_join(int a, int b) 33 { 34 int n1 = my_find(a), n2 = my_find(b); 35 my_pre[n1] = n2; 36 } 37 38 int my_kruskal() 39 { 40 /** 41 Initialize 42 */ 43 int my_ans = 0; 44 sort(my_dis, my_dis + my_line, cmp); 45 for (int i = 1; i <= n; ++ i) 46 my_pre[i] = i; 47 48 for (int i = 0; i < my_line; ++ i) 49 { 50 int a = my_find(my_dis[i].a), b = my_find(my_dis[i].b); 51 if (a != b) 52 { 53 my_pre[a] = b; 54 my_ans += my_dis[i].a_b_dis; 55 } 56 } 57 58 return my_ans; 59 } 60 61 int main() 62 { 63 while (scanf("%d", &n), n) 64 { 65 my_line = n * (n-1) / 2; 66 for (int i = 0; i < my_line; ++ i) 67 scanf("%d%d%d", &my_dis[i].a, &my_dis[i].b, &my_dis[i].a_b_dis); 68 printf("%d\n", my_kruskal()); 69 } 70 return 0; 71 }