明明是最小生成树,分类却放在计算几何里面了。。。
每个小球是一个点,点之间的距离是球面之前的距离,如果两球覆盖,距离为0,然后prim
#include <cstdio>
#include <cstring>
#include <cmath>
const int MAXN = 110;
const double INF = 1000.0;
const double eps = 1e-10;
struct Circle
{
double x,y,z,r;
};
Circle coor[MAXN];
double g[MAXN][MAXN];
double dis[MAXN];
bool book[MAXN];
double distance(int i, int j)
{
double d1 = coor[i].x - coor[j].x;
double d2 = coor[i].y - coor[j].y;
double d3 = coor[i].z - coor[j].z;
double dd = sqrt(d1*d1 + d2*d2 + d3*d3);
double ret = dd - coor[i].r - coor[j].r;
return ret;
}
int EPS(double k)
{
if(fabs(k) < eps)
return 0;
return k > 0 ? 1 : -1;
}
int main()
{
int n;
double d;
while(scanf("%d",&n) && n)
{
memset(book,0,sizeof(book));
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= n; ++j)
g[i][j] = INF;
for(int i = 1; i <= n; ++i)
scanf("%lf %lf %lf %lf",&coor[i].x,&coor[i].y,&coor[i].z,&coor[i].r);
for(int i = 1; i <= n-1; ++i)
{
g[i][i] = 0;
for(int j = i+1; j <= n; ++j)
{
d = distance(i,j);
if(EPS(d) <= 0) g[i][j] = g[j][i] = 0;
else g[i][j] = g[j][i] = d;
}
}
for(int i = 1; i <= n; ++i)
dis[i] = g[1][i];
int cnt = 1,rec;
double sum = 0,minn;
book[1] = true;
while(cnt < n)
{
minn = INF;
for(int i = 1; i <= n; ++i)
{
if(!book[i] && dis[i] < minn)
{
minn = dis[i];
rec = i;
}
}
book[rec] = true;
sum += dis[rec];
++cnt;
for(int i = 1; i <= n; ++i)
{
if(!book[i] && dis[i] > g[rec][i])
dis[i] = g[rec][i];
}
}
printf("%.3f\n",sum);
}
return 0;
}