hdu 1233 (prim,最小生成树) 还是畅通工程
还是畅通工程
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 54905 Accepted Submission(s): 24918
Problem Description
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
Input
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
当N为0时,输入结束,该用例不被处理。
Output
对每个测试用例,在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
Sample Output
3
5
Hint
Huge input, scanf is recommended.
/** 这道题是求一条连接各个连通区域的线使其距离最短 算法:prim **/
可以参照:
http://www.cnblogs.com/GetcharZp/p/8944400.html
C/C++代码实现
#include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <cstdio> #include <stack> #include <queue> #define my_max 0x3f3f3f3f using namespace std; int n, my_map [105][105], a, b, c; int prim () { int cnt = 0, pos = 1, my_weight [105], my_book [105] = {0, 1}; for (int i = 1; i <= n; ++ i) { if (! my_book [i]) { my_weight [i] = my_map [pos][i]; } } for (int i = 1; i < n; ++ i) { int my_min = my_max; for (int j = 1; j <= n; ++ j) { if (!my_book [j] && my_min > my_weight [j]) { pos = j; my_min = my_weight [j]; } } cnt += my_min; my_book [pos] = 1; // 标记已连通的所用点 for (int j = 1; j <= n; ++ j) // 对未被标记的点求其到已标记点的最短距离 { if (!my_book [j] && my_weight [j] > my_map [pos][j]) { my_weight [j] = my_map [pos][j]; } } } return cnt ; } int main () { while (scanf ("%d", &n), n) { int N = n * (n - 1) / 2; for (int i = 0; i < N; ++ i) { scanf("%d%d%d", &a, &b, &c); my_map [a][b] = my_map [b][a] = c; } printf ("%d\n", prim ()); } }