水题,求3维坐标距离,再求最小生成树。
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#define INF 1e-8
using namespace std;
typedef struct
{
double x,y,z,r;
}node;
typedef struct
{
int x,y;
double dis;
}bian;
node a[200];
bian b[40000];
int n,bn;
int fa[300];
double dis(int i,int j)
{
double d;
d = sqrt( (a[i].x-a[j].x)*(a[i].x-a[j].x) +
(a[i].y-a[j].y)*(a[i].y-a[j].y) +
(a[i].z-a[j].z)*(a[i].z-a[j].z) ) - a[i].r - a[j].r;
if(d < INF) d = 0;
//printf("%f\n",a[i].r);
return d;
}
void init()
{
for(int i=1;i<=n;i++)
scanf("%lf %lf %lf %lf",&a[i].x,&a[i].y,&a[i].z,&a[i].r);
bn = 0;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
{ b[++bn].dis = dis(i,j);
b[bn].x = i; b[bn].y = j;
//printf("%d %d %f\n",i,j,b[bn].dis);
}
}
int find(int w)
{
int k;
if(fa[w] == w) return w;
k = find(fa[w]);
fa[w] = k;
return k;
}
bool cmp(const bian &a,const bian &b)
{
return a.dis < b.dis;
}
void solve()
{
int i,j,k,r,w,h;
double ans;
sort(b+1,b+bn+1,cmp);
for(i=1;i<=n;i++) fa[i] = i;
h = ans = 0;
for(i=1;i<=bn;i++)
{ if(h == n-1) break;
r = find(b[i].x);
w = find(b[i].y);
if( r != w )
{ fa[r] = w;
h++;
ans += b[i].dis;
}
//printf("%d %d\n",r,w);
}
printf("%0.3f\n",ans);
}
int main()
{
while(scanf("%d",&n) != EOF && n)
{ init();
solve();
}
return 0;
}