最小生成树,prime 或者kruskal都可以吧,我用的prime算法。
看上去是个空间的问题,其实就是一个大水题~
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAX 111
#define maxlen 1000000.0
using namespace std;
struct Node
{
double x,y,z,r;
};
Node node[MAX];
double map[MAX][MAX],lowcost[MAX];
int used[MAX],n;
double dis(int i,int j)
{
double x,y,z,d;
x=node[i].x-node[j].x;
y=node[i].y-node[j].y;
z=node[i].z-node[j].z;
d=sqrt(x*x+y*y+z*z);
d=d-node[i].r-node[j].r;
if(d<=0) return 0.0;
return d;
}
void init()
{
int i,j;
for(i=1;i<=n;i++)
scanf("%lf%lf%lf%lf",&node[i].x,&node[i].y,&node[i].z,&node[i].r);
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(j<i) map[i][j]=map[j][i];
else if(i==j) map[i][j]=0.0;
else
{
map[i][j]=dis(i,j);
}
}
}
}
double MST()
{
int i,j,pos;
double MIN,ans=0.0;
memset(used,0,sizeof(used));
used[1]=1;pos=1;
for(i=1;i<=n;i++)
{
if(i!=pos) lowcost[i]=map[pos][i];
}
for(i=1;i<n;i++)
{
MIN=maxlen;
for(j=1;j<=n;j++)
{
if(!used[j]&&MIN>lowcost[j])
{
MIN=lowcost[j];pos=j;
}
}
ans+=MIN;
used[pos]=1;
for(j=1;j<=n;j++)
{
if(!used[j]&&lowcost[j]>map[pos][j])
lowcost[j]=map[pos][j];
}
}
return ans;
}
int main()
{
int i,j;
while(scanf("%d",&n)==1)
{
if(n==0) break;
init();
printf("%0.3lf\n",MST());
}
return 0;
}