畅通工程
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 27097 Accepted Submission(s): 11840
Problem Description
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。
Input
测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 N
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从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
Sample Output
3
?
Source
浙大计算机研究生复试上机考试-2007年
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <stdio.h> #include <algorithm> #include <math.h> #include <string.h> using namespace std; class Union_Find_Set { #define MAX_UNION_FIND_SET_SIZE 105 public: int setSize; int father[MAX_UNION_FIND_SET_SIZE]; Union_Find_Set() { setSize = 0; } Union_Find_Set(int x) { setSize = x; clear(x); } void clear(int x) { for (int i = 0; i < x; i++) { father[i] = i; } } int getFather(int x) { if (x != father[x]) { father[x] = getFather(father[x]); } return father[x]; } bool merge(int a, int b) { a = getFather(a); b = getFather(b); if (a != b) { father[a] = b; return true; } else { return false; } } int countRoot() { int ret = 0; for (int i = 0; i < setSize; i++) { if (father[i] = i) { ret++; } } return ret; } }; class Kruskal { #define Kruskal_MAXN 100 #define Kruskal_MAXM 10005 public: Union_Find_Set ufs; int x[Kruskal_MAXM], y[Kruskal_MAXM], w[Kruskal_MAXM], N, M; Kruskal() { N = 0; M = 0; } void clear() { N = 0; M = 0; } void addEdge(int a, int b, int c) { x[M] = a; y[M] = b; w[M] = c; M++; x[M] = b; y[M] = a; w[M] = c; M++; } void sort(int l, int r) { int i = l, j = r, m = w[(l + r) >> 1], t; do { while (w[i] < m) { i++; } while (m < w[j]) { j--; } if (i <= j) { t = x[i]; x[i] = x[j]; x[j] = t; t = y[i]; y[i] = y[j]; y[j] = t; t = w[i]; w[i] = w[j]; w[j] = t; i++; j--; } } while (i <= j); if (l < j) { sort(l, j); } if (i < r) { sort(i, r); } } int MST() { sort(0, M - 1); ufs.clear(N + 1); int cnt = 0, ret = 0; for (int i = 0; i < M; i++) { if (cnt == N - 1) { return ret; } if (ufs.getFather(x[i]) != ufs.getFather(y[i])) { ufs.merge(x[i], y[i]); ret += w[i]; cnt++; } } if (cnt == N - 1) { return ret; } else { return -1; } } }; Kruskal Kr; int main() { int n, m; while (scanf("%d%d", &m, &n) != EOF) { if (m == 0) { break; } Kr.clear(); Kr.N = n; for (int i = 0; i < m; i++) { int a, b, c; scanf("%d%d%d", &a, &b, &c); Kr.addEdge(a, b, c); } int ans = Kr.MST(); if (ans == -1) { printf("? "); } else { printf("%d ", ans); } } return 0; }