33,027
社区成员




#include<stdio.h>
#include<string.h>
#include<math.h>
#define M 105
int n,p,i,j,parent[M];
/*
n=测资笔数
p=点的数目
parent=生成树上的父点
*/
double dis[M][M],point[M][2],d[M];
/*
dis[i][j]代表由i到j的距离
point[i][0],point[i][1]代表第i个点的x座标和y座标
d[i]代表i点到生成树上的最短距离
*/
bool visited[M],first=true;
//visited 判断有无访问过该点
//first 第一笔测资,判断presentation用
void get_dis()//求两点之间的距离(座标转换成距离)
{
for(i=0;i<p;i++)
{
dis[i][i]=0;
for(j=i+1;j<p;j++)
dis[i][j]=dis[j][i]=sqrt((point[i][0]-point[j][0])*(point[i][0]-point[j][0])+(point[i][1]-point[j][1])*(point[i][1]-point[j][1]));
}
}
double prim()//shortest spaning tree
{
double r=0;//生成树的总距离大小
memset(visited,false,sizeof(visited));
for(i=0;i<p;i++)d[i]=2*1e9;
d[0]=0;
parent[0]=0;
for(i=0;i<p;i++)
{
int a=-1,b=-1;
double min=2*1e9;
for(j=0;j<p;j++)
if(!visited[j]&&d[j]<min)
{
a=j;
min=d[j];
}
if(a==-1)break;
r+=min;
visited[a]=true;
for(b=0;b<9;b++)
if(!visited[b]&&dis[a][b]<d[b])
{
d[b]=dis[a][b];
parent[b]=a;
}
}
return r;
}
int main()
{
scanf("%d",&n);
while(n--)
{
scanf("%d",&p);
for(i=0;i<p;i++)scanf("%lf %lf",&point[i][0],&point[i][1]);
get_dis();
if(first)first=false;
else puts("");
printf("%.2lf\n",prim());
}
return 0;
}