这一题是并查集的题,和hdu1232有一些不同。
输入的时候用到了struct结构体,这样两个城镇才会和它们之间的距离紧紧“绑”在一起,不会因为用sort排序后,找不到每个距离所对应的两个城镇。
根据距离把struct结构体从小到大排序(用sort对struct结构体排序的方法),然后用for循环遍历排序后的结构体,如果两个城镇的还未连接,就连接它们,并在总距离中加上这两个城镇的距离;
#include<stdio.h>
#include<algorithm>
using namespace std;
int m,n,pre[1010],ran[1010];
struct edge
{
int a;
int b;
int c;
}s[5110];
int cmp(edge a,edge b)
{
return a.c<b.c;
}
void unit(int a)
{
for(int i=1;i<=a;i++)
pre[i]=i,ran[i]=1;
}
int find(int x)//找祖先函数,find(a)的返回值即是a的祖先
{
int t=x;//把x存在t中
while(x!=pre[x]) x=pre[x];//通过不断的找父亲操作,最终找到x的祖先
if(t!=x)//这个if循环是个优化 ,避免树太长,查找超时。
{
int r=pre[t];//暂存t的父亲
pre[t]=x;
t=r;
}
return x;
}
int un(int a,int b)//连接a,b到一棵树上
{
a=find(a);
b=find(b);
if(a==b)//a,b的祖先一样,那么就不需要连接了
return 0;
if(ran[a]>=ran[b])//a比b长,把b接到a树上
{
pre[b]=a;
ran[a]+=ran[b];
}
else//b比a长,把a接到b树上
{
pre[a]=b;
ran[b]+=ran[a];
}
}
int main()
{
int i,j,a,b,c;
while(scanf("%d",&n)!=EOF)
{
if(n==0)
break;
unit(n); //对n个城镇初始化
m=n*(n-1)/2;
for(i=1;i<=m;i++)
scanf("%d%d%d",&s[i].a,&s[i].b,&s[i].c);
sort(s+1,s+1+m,cmp);//从小到大排序
int num=0;
for(i=1;i<=m;i++)
if(find(s[i].a)!=find(s[i].b))//判断两个城镇是否已经连接
{
num+=s[i].c;//在总距离中加上这两个城镇的距离
un(s[i].a,s[i].b);//连接两个城镇
}
printf("%d\n",num);
}
}