DescriptionDescriptionDescription
给出N个点的坐标,对它们建立一个最小生成树,代价就是连接它们的路径的长度,现要求总长度最小。N的值在100以内,坐标值在[-10000,10000].结果保留二位小数
InputInputInput
第一行nnn,第222到n+1n+1n+1行为第iii个点的坐标
OutputOutputOutput
他们的最小生成树
SampleInputSample InputSampleInput
5
0 0
0 1
1 1
1 0
0.5 0.5
SampleOutputSample OutputSampleOutput
2.83
思路
先用勾股定理建边
然后用KruskalKruskalKruskal
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
struct whw
{
double x,s,y;
}wh[6250250];
double Place[225][2];
double Ans;
int Fa[5025];
int n,t;
int Find(int k)
{
while(Fa[k]!=k)k=Fa[k];
return k;
}
//bool Fi()
//{
// int k=Find(1);
// for(int i=2;i<=n;++i)
// if(k!=Find(i))return 0;
// else k=Find(i);
//}
bool Cmp(whw i,whw j)
{return i.s<j.s;}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
scanf("%lf%lf",&Place[i][0],&Place[i][1]);
for(int j=1;j<i;++j)//建边
{
wh[++t].x=i;wh[t].y=j;
double xx=abs(Place[i][0]-Place[j][0]);
double yy=abs(Place[i][1]-Place[j][1]);
wh[t].s=sqrt(xx*xx+yy*yy);
}
Fa[i]=i;
}
sort(wh+1,wh+t+1,Cmp);
for(int i=1;i<=t;++i)
// if(!Fi())//优化,防止所有点都在一个集合里却还在搜(貌似更慢了)
{
int x=Find(wh[i].x);
int y=Find(wh[i].y);
if(x!=y)
{
Fa[max(x,y)]=Fa[min(x,y)];
Ans+=wh[i].s;
}
}
printf("%.2lf",Ans);
return 0;
}