代码如下,含注解:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<math.h>
using namespace std;
int f[150],sum[150];//f[i]为i的父节点,sum[i]为以i为根节点时其子节点数量;
double ans;
struct node1
{
double x;
double y;
int id;//每个位置的id,坐标;
}a[150];
struct node2
{
double dis;
int id1,id2;//每两个岛之间的距离;
}b[10050];
inline void ini(int n)
{
int i;
for(i=1;i<=n;i++)
{
f[i]=i;
sum[i]=1;
a[i].id=i;
}
}
bool cmp(node2 x,node2 y)//按照距离从小到大排序,类似贪心的思想;
{
return x.dis<y.dis;
}
int find(int x)//并查集+路径压缩;
{
while(x!=f[x])
{
f[x]=f[f[x]];
x=f[x];
}
return x;
}
int main()
{
int i,j;
int n,m;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
ini(n);
ans=0;
for(i=1;i<=n;i++)
{
scanf("%lf%lf",&a[i].x,&a[i].y);
}
int pos=0;
for(i=1;i<=n;i++)
{
for(j=i+1;j<=n;j++)
{
b[++pos].dis=((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));
b[pos].id1=a[i].id;
b[pos].id2=a[j].id;
}
}
sort(b+1,b+1+pos,cmp);
for(i=1;i<=pos;i++)
{
if(b[i].dis>=100.0&&b[i].dis<=1000000.0)//找出符合条件的节点;
{
int fa,fb;
fa=find(b[i].id1);
fb=find(b[i].id2);
if(fa!=fb)//如果未连接,则按距离小到大连起来;
{
if(sum[fa]>sum[fb])
{
f[fb]=fa;
sum[fa]+=sum[fb];
}
else
{
f[fa]=fb;
sum[fb]+=sum[fa];
}
ans+=sqrt(b[i].dis)*100.0;
}
}
}
//bool flag=true;
int x=find(a[1].id);//找树的根节点;
if(sum[x]==n)//如果根节点包含了所有的节点,说明成功;
{
printf("%.1lf\n",ans);
}
else
{
printf("oh!\n");
}
}
return 0;
}