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;
}

  

posted @ 2012-05-24 21:37  E_star  阅读(225)  评论(0编辑  收藏  举报