【2017/2/25】
[题目: 还是畅通工程] http://ac.jobdu.com/problem.php?pid=1017
很简单的题目,克鲁斯卡尔标准步骤!
【注意:本例测试点均满足有最小生成树,若可能出现不存在最小生成树的 情况,则需要在最后判断 是否所有点属于同一个集合<九度1024继续畅通工程>,如下:】
int MST = 0; //判断是否为最小生成树【本题并不需要】
for (int i = 1; i <= n; i++) {
if (-1 == tree[i])
MST++; //若最后MST=1,则成功
}
#include<cstdio>
#include<algorithm>
#define maxSize 10005
using namespace std;
struct Road {
int a, b;
int len;
}road[maxSize];
int tree[105];
bool cmp(Road A, Road B) {
return A.len < B.len;
}
int findRoot(int x) {//寻根
if (-1 == tree[x]) return x;
else {
int temp = findRoot(tree[x]);
tree[x] = temp; //路径压缩
return temp;
}
}
int main() {
int n;
while (scanf("%d", &n) != EOF) {
if (0 == n) break;
for (int i = 1; i <= n; i++) {//初始化
tree[i] = -1;
}
int m = n * (n - 1) / 2;
for (int i = 1; i <= m; i++)
scanf("%d%d%d", &road[i].a, &road[i].b, &road[i].len);
sort(road + 1, road + m + 1, cmp);//按长度递减排序
int sum = 0;
for (int i = 1; i <= m; i++) {//遍历所有边
int a = findRoot(road[i].a);
int b = findRoot(road[i].b);
if (a != b) {
tree[a] = b;
sum += road[i].len;
}
}
printf("%d\n", sum);
}
return 0;
}