边数较少可以用Kruskal,因为Kruskal算法每次查找最短的边。 边数较多可以用Prim,因为它是每次加一个顶点,对边数多的适用。
用Prim。
#include<stdio.h>
#include<string.h>
#include<math.h>
const double INF=99999;
struct z{
int x,y;
int cas;
}node[300];
double xxx(int a,int b,int x,int y){
return sqrt((a-x)*(a-x)*1.0+(b-y)*(b-y)*1.0);
}
double small(double a,double b){
return a>b?b:a;
}
double mat[2000][2000];
double map[2000][2000];
double prim(int n){
int i,min_i,j;
double Min,sum=0;
double dis[3000];
int flag[3000];
for( i=1 ; i <=n ; i++ )
dis[i] = mat[i][1];
memset( flag, 0, sizeof(flag));
flag[1] = 1;
for( i=2 ; i <=n ; i++ ) {
Min = INF;min_i=i;
for( j=2 ; j <=n ; j++ ){
if(flag[j]==0 && dis[j]<Min){
Min=dis[j];
min_i=j;
}
}
if(Min==INF)
break;
sum += Min;
flag[min_i] = 1;
for( j=2 ; j <=n ; j++ ){
if(flag[j]==0 && dis[j]>mat[min_i][j])
dis[j] = mat[j][min_i];
}
}
return sum;
}
int main(){
int t,n,i,j,k;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d %d",&node[i].x,&node[i].y);
node[i].cas=i;
}
int num=0;
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
mat[i][j]=INF;
}
}
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(i==j)
continue;
int x=node[i].cas;
int y=node[j].cas;
map[x][y]=xxx(node[i].x,node[i].y,node[j].x,node[j].y);
map[y][x]=xxx(node[i].x,node[i].y,node[j].x,node[j].y);
num++;
}
}
double ans=INF*2;
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
for(k=1;k<=n;k++){
mat[j][k]=map[j][k];
}
}
for(j=1;j<=n;j++){
mat[j][i]=INF-1;
mat[i][j]=INF-1;
}
ans=small(prim(n),ans);
ans=ans;
}
printf("%.2lf\n",ans-INF+1);
}
}