用最短距加并查集写出了最小树的效果
留个纪念吧~
#include <iostream>
using namespace std;
#define INF 10000
int a[1000][1000],n,d[INF];
int pre[105],sum;
void Init()
{
for(int i=0;i<=150;i++)
{
for(int j=0;j<150;j++)
{
if(i==j)
a[i][j]=0;
else
a[i][j]=INF;
}
}
}
void floyd()
{
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(a[i][j]>a[i][k]+a[k][j])
a[i][j]=a[i][k]+a[k][j];
}
}
}
}
int find(int x)
{
int r=x;
while(pre[r]!=r)
r=pre[r];
int i=x,j;
while(pre[i]!=r)
{
j=pre[i];
pre[i]=r;
i=j;
}
return r;
}
void mix(int x,int y)
{
int r=find(x);
int l=find(y);
if(l!=r)
pre[l]=r;
}
void insert()
{
while(1)
{
int min=100000,ii,jj,c,b;
int flag=0;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
if(min>a[i][j])
{
c=find(i);
b=find(j);
if(c!=b)
{
ii=i;
jj=j;
min=a[i][j];
flag=1;
}
}
}
}
if(flag==0)
break;
c=find(ii);
b=find(jj);
//printf("%d->%d %d->%d\n",ii,c,jj,b);
sum+=min;
mix(ii,jj);
a[ii][jj]=100005;
}
}
int main()
{
int i,j,w;
while(~scanf("%d",&n)&&n!=0)
{
Init();
int m=n*(n-1)/2;
for(int k=0;k<m;k++)
{
scanf("%d %d %d",&i,&j,&w);
a[i][j]=a[j][i]=w;
}
floyd();
for(int i=1;i<=n;i++)
pre[i]=i;
sum=0;
insert();
cout<<sum<<endl;
/*for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
printf("%d ",a[i][j]);
printf("\n");
}*/
}
return 0;
}