pku 2031 Building a Space Station 最小生成树+精度控制
http://poj.org/problem?id=2031
题意就是给你n个球的(球心以及半径),然后求最小生成树就欧了,这里的关键部分是对于重复的球的路径长度的处理
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#define maxn 107
#define inf 999999999
using namespace std;
const double eps = 1e-6;
struct node
{
double x,y,z,r;
}p[maxn];
double map[100][100],dis[maxn];
bool vt[maxn];
int n;
int cmp(double x)
{
if (x > eps) return 1;
else if (x < -eps) return -1;
else return 0;
}
double getlens(int i,int j)
{
double x = p[i].x - p[j].x;
double y = p[i].y - p[j].y;
double z = p[i].z - p[j].z;
double d = (sqrt(x*x + y*y + z*z) - p[i].r - p[j].r);
if (cmp(d) < 0) return 0;//如果有重复的出现,返回0
else return d;
}
void prim()
{
int i,j,k;
double min;
double ans = 0;
for (i = 0; i < n; ++i)
{
vt[i] = false;
dis[i] = map[0][i];
}
vt[0] = true;
for (k = 1; k < n; ++k)
{
j = 0; min = inf;
for (i = 1; i < n; ++i)
{
if (!vt[i] && min > dis[i])
{
j = i; min = dis[i];
}
}
vt[j] = true;
ans += min;
for (i = 1; i < n; ++i)
{
if (!vt[i])
{
if (dis[i] > map[i][j])
dis[i] = map[i][j];
}
}
}
printf("%.3lf\n",ans);
}
int main()
{
int i,j;
while (~scanf("%d",&n))
{
if (!n) break;
for (i = 0; i < n; ++i)
scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&p[i].z,&p[i].r);
for (i = 0; i < n; ++i)
{
for (j = 0; j < n; ++j)
{
map[i][j] = (i != j)*inf;
}
}
/*for (i = 0; i < n; ++i)
{
for (j = 0; j < n; ++j)
{
printf("%.3lf ",map[i][j]);
}
printf("\n");
}*/
for (i = 0; i < n; ++i)
{
for (j = i; j < n; ++j)
{
map[i][j] = map[j][i] = getlens(i,j);
}
}
prim();
}
return 0;
}


浙公网安备 33010602011771号