分析:题目给出村庄的数目,每两个村庄间的距离,求使村庄连通起来时铺设公路的最小总长度。使用Kruskal算法。
#include <iostream>
#include <cstdio>
#include <algorithm>
//最小生成树,求连通各个城市的公路总长度最小。
using namespace std;
const int MAXN = 100;
struct Edge{
int from;
int to;
int length;
bool operator< (const Edge& e) const{ //重载运算符的写法
return length<e.length;
}
};
Edge edge[MAXN * MAXN];//边
int father[MAXN];
int height[MAXN];
void Initial(int n){
for(int i = 0 ; i <=n ;i++ ){
father[i] = i;
height[i] = 0;
}
return ;
}
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[x] = y;
}else if(height[x] > height[y]){
father[y] = x;
}else {
father[y] = x;
height[x] ++;
}
}
}
int Kruskal(int n,int edgeNumber){ //点的数目和边的数目。
Initial(n);
sort(edge,edge+edgeNumber);
int sum = 0 ; //权值之和
for(int i = 0 ; i < edgeNumber;i++){
Edge current = edge[i]; //当前的边是权值最小的边
if(Find(current.from) != Find(current.to)){ //如果两个点不在同一个集合中,则边的终点未收录
Union(current.from,current.to);
sum += current.length;
}
}
return sum;
}
int main(){
int n;
while(cin>>n){
if(n == 0 ){
break;
}
int edgeNumber = n *(n-1) / 2; //道路数目
for(int i = 0 ; i < edgeNumber ;i++){
cin>>edge[i].from>>edge[i].to>>edge[i].length;
}
int answer = Kruskal(n,edgeNumber);
cout<<answer<<endl;
}
return 0;
}