1.使用结构数组存储所有的边的信息。
2.对所有边按照边的权值进行从小到大排序。
3.根据Kruskal算法,来自不同的分支,找到尽可能小权值的边将其联通起来。也就是说,在边按照权值排序后,每加入一条边,如果这条边的两个结点来自不同分支(采用并查集方式来记录同一分支),则可以使用这条边将两个分支联通。
//最小生成树(Kruskal)
//还是畅通工程
#include<iostream>
#include<cstring>
#include<algorithm>
#define N 6001
using namespace std;
int Tree[101];
struct E{
int A,B;
int cost;
bool operator < (const E &e) const{
return cost<e.cost;
}
};
int findRoot(int x){
if(Tree[x]==-1) return x;
else return findRoot(Tree[x]);
}
E edge[6001];
int main(void){
int n,m;
while(cin>>n){
if(n==0) break;
for(int i=1;i<=n*(n-1)/2;i++){
cin>>edge[i].A>>edge[i].B>>edge[i].cost;
}
for(int i=1;i<=n;i++){
Tree[i]=-1;
}
sort(edge+1,edge+1+n*(n-1)/2);//排序所有的边
int sum=0;
for(int i=1;i<=n*(n-1)/2;i++){
int na = edge[i].A;
int nb = edge[i].B;
int c = edge[i].cost;
na = findRoot(na);
nb = findRoot(nb);//利用并查集来记录它们是否在一个分支
if(na!=nb){
Tree[na]=nb;//没有在同一个分支则合并
sum += c;
}
}
cout<<sum<<endl;
}
return 0;
}
/*
Input:
3
1 2 1
1 3 2
2 3 4
4
1 2 1
1 3 4
1 4 1
2 3 3
2 4 2
3 4 5
0
Output:
3
5
*/