题目链接:http://poj.org/problem?id=2031
n个球型的cell,如果任意两个球表面没有接触或者没有包含关系,就选择最近的表面建立通道;
所以用maps[i][j]表示i,j之间的距离;最后求所有连接的和的最小值;
注意:
poj上:对于双精度输出,G++上面要用%f,C++则用%lf,否则WA
#include<stdio.h>
#include<string.h>
#include<map>
#include<iostream>
#include<algorithm>
#include<math.h>
#define N 110
#define INF 0xfffffff using namespace std; int vis[N], n;
double maps[N][N], dist[N]; struct node
{
double x, y, z, r;
}a[N*N]; void Init()
{
int i;
memset(a, ,sizeof(a));
memset(vis, ,sizeof(vis));
for(i=; i<=n; i++)
{
dist[i] = INF;
for(int j=; j<=n; j++)
{
maps[i][j] = INF;
}
maps[i][i] = ;
}
} double Prim(int start)
{
double ans = ;
vis[start] = ;
for(int i=; i<=n; i++)
dist[i] = maps[start][i];
for(int i=; i<=n; i++)
{
double Min = INF;
int index = -;
for(int j=; j<=n; j++)
{
if(vis[j] == && Min > dist[j])
{
Min = dist[j];
index = j;
}
}
if(index == -)break;
vis[index] = ;
ans += Min;
for(int j=; j<=n; j++)
{
if(vis[j] == && dist[j] > maps[index][j])
dist[j] = maps[index][j];
}
}
return ans;
} int main()
{
int i, j;
double ans, x, y, z, d;
while(scanf("%d", &n), n)
{
Init();
for(i=; i<=n; i++)
{
scanf("%lf%lf%lf%lf", &a[i].x, &a[i].y, &a[i].z, &a[i].r);
}
for(i=; i<=n; i++)
{
for(j=i+; j<=n; j++)
{
x = a[i].x - a[j].x;
y = a[i].y - a[j].y;
z = a[i].z - a[j].z;
d = sqrt( x*x + y*y + z*z );
if(d > a[i].r + a[j].r)
{
maps[i][j] = maps[j][i] = d - a[i].r - a[j].r;
}
else
{
maps[i][j] = maps[j][i] = ;
}
}
}
ans = Prim();
printf("%.3lf\n", ans);
}
return ;
}