还是畅通工程

来源:互联网 发布:点击按钮执行php代码 编辑:程序博客网 时间:2024/06/05 00:08

还是畅通工程

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 156    Accepted Submission(s): 120

 
Problem Description
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
Input
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
当N为0时,输入结束,该用例不被处理。
Output

            对每个测试用例,在1行里输出最小的公路总长度。
Sample Input
31 2 11 3 22 3 441 2 11 3 41 4 12 3 32 4 23 4 50
Sample Output
35
 
#include<cstdio>#include<algorithm>using namespace std;const int MAXN = 100 + 10;const int MAXM = 5000 + 10;int u[MAXM], v[MAXM], w[MAXM], r[MAXM];int p[MAXN];int cmp(int i, int j){return w[i] < w[j];}int find_set(int i){if(i != p[i]){p[i] = find_set(p[i]);}return p[i];}void union_set(int i, int j){int a = find_set(i);int b = find_set(j);p[b] = a;}int main(){int n, a, b, k;while(scanf("%d", &n) && n){int m = (n * (n - 1)) >> 1;int cnt = 0; for(int i = 0; i < m; i++){scanf("%d%d%d", &a, &b, &k);u[i] = a;v[i] = b;w[i] = k;}for(int i = 1; i <= n; i++) p[i] = i;for(int i = 0; i < m; i++) r[i] = i;sort(r, r + m, cmp);for(int i = 0; i < m; i++){int e = r[i];int a = find_set(u[e]);int b = find_set(v[e]);if(a != b){union_set(a, b);cnt += w[e];}}printf("%d\n", cnt);}return 1;}

Hint
Hint
 Huge input, scanf is recommended.
0 0