测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M (N, M < =100 );随后的 N 行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。
3 3 1 2 1 1 3 2 2 3 4 1 3 2 3 2 0 100
3 ?
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
struct Point{
int x;
int y;
};
struct Edge{
int from;
int to;
int cost;
};
int father[101];
struct Edge edge[101];
int height[101];
void inital(int n){
for(int i = 1; i <= n; i++){
father[i] = i;
height[i] = 1;
}
}
int cmp(const void*a, const void*b ){
struct Edge* edgea = (struct Edge *) a;
struct Edge* edgeb = (struct Edge *) b;
if(edgea->cost < edgeb->cost) return -1;
else if(edgea->cost > edgeb->cost) return 1;
return 0;
}
int Find(int x) {
if (x != father[x])
father[x] = Find(father[x]);
return father[x];
}
void Union(int x, int y) {
x = Find(x);
y = Find(y);
if (x != y) {
if (height[x] > height[y])
father[y] = x;
else if (height[y] > height[x])
father[x] = y;
else {
father[y] = x;
height[x]++;
}
}
}
int kruskal(struct Edge edge[], int edgenum){
int ans = 0;
qsort(edge, edgenum, sizeof(struct Edge), cmp);
for(int i = 0; i < edgenum; i++){
if(Find(edge[i].from) != Find(edge[i].to)){
Union(edge[i].from, edge[i].to);
ans += edge[i].cost;
}
}
return ans;
}
int main(){
int n, m, a, b, c, res, x, y;
while(scanf("%d %d", &n, &m)!=EOF){
if (n == 0) break;
inital(m);
for(int i = 0; i < n; i++){
scanf("%d %d %d", &edge[i].from, &edge[i].to, &edge[i].cost);
}
res = kruskal(edge, n);
x = father[1];
int tag = 0;
for(int i = 2; i <= m; i++){
y = Find(i);
if (x != y) {
tag = 1;
break;
}
}
if(tag == 0)
printf("%d\n",res);
else
printf("%s\n", "?");
}
return 0;
}