因为要总长度最小,所以想到贪心,使用Kruskal算法的思想构造最小生成树即可:
#include<iostream>
#include<string>
#include<queue>
using namespace std;
const int N = 100 + 10;
int arr[N];
struct Distance{
int n1, n2;
int dis;
Distance(int n1, int n2, int d): n1(n1), n2(n2), dis(d){}
bool operator>(Distance d) const{
return dis > d.dis;
}
};
void Initial(int *arr, int n){
for(int i = 1; i <= n; i++) arr[i] = -1;
}
int Find(int *arr, int x){
int root = x;
while(arr[root] > 0) root = arr[root];
while(x != root){
int t = arr[x];
arr[x] = root;
x = t;
}
return root;
}
bool Union(int *arr, int x, int y){
int root1 = Find(arr, x);
int root2 = Find(arr, y);
if(root1 != root2){
if(arr[root2] > arr[root1]){
arr[root1] += arr[root2];
arr[root2] = root1;
}else{
arr[root2] += arr[root1];
arr[root1] = root2;
}
return true;
}
return false;
}
int main(){
int n, a, b, dis;
while(scanf("%d", &n) != EOF){
if(n == 0) break;
int len = (n - 1) * n / 2;
priority_queue<Distance, vector<Distance>, greater<Distance>> pq;
Initial(arr, n);
for(int i = 0; i < len; i++){
scanf("%d%d%d", &a, &b, &dis);
pq.push(Distance(a, b, dis));
}
len = pq.size();
int sum = 0;
for(int i = 0; i < len; i++){
Distance d = pq.top();
pq.pop();
if(Union(arr, d.n1, d.n2)) sum += d.dis;
}
printf("%d\n", sum);
}
return 0;
}