POJ2031 Building a Space Station【最小生成树】

题意:

就是给出三维坐标系上的一些球的球心坐标和其半径,搭建通路,使得他们能够相互连通。如果两个球有重叠的部分则算为已连通,无需再搭桥。求搭建通路的最小边长总和是多少。

思路:

先处理空间点之间的距离,要注意的是两个球面相交的情况,相交的话距离是0。两球面距离是球心距离减去两个球的半径(边权 = AB球面距离 = A球心到B球心的距离 – A球半径 – B球半径),相交时距离是算出来是负值,要改为0。其实就是求连接所有球最小生成树的过程。

代码:

kruskal:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;

int n;
double need;

struct Station    //定义球的结构体
{
    double x,y,z;
    double r;
};
Station station[110];

struct Vdge    //构造生成树的点
{
    int x,y;
    double l;
};

bool cmp(Vdge a,Vdge b){
    return a.l < b.l ;
}

Vdge edge[5500];
int road[110];

int find(int x)
{
    while( x != road[x] )
        x = road[x];
    return x;
}

bool judge(int x,int y){
    int fx = find(x);
    int fy = find(y);
    if( fx==fy )
        return false;
    else
    {
        road[fx] = fy;
        return true;
    }
}

double dis(int i,int j)
{
    double distance;
    double a = pow(station[i].x-station[j].x , 2);
    double b = pow(station[i].y-station[j].y , 2);
    double c = pow(station[i].z-station[j].z , 2);
    distance = sqrt(a+b+c);
    distance -= station[i].r + station[j].r;
    if( distance <= 0 ) distance = 0;
    return distance;
}

void init()
{
    for(int i=0 ; i<n ; i++)
        scanf("%lf %lf %lf %lf",&station[i].x,&station[i].y,&station[i].z,&station[i].r);
    for(int i=0 ; i<n ; i++)
        road[i] = i;
    need = 0;
    int k = 0;
    for(int i=0 ; i<n ; i++)
    {
        for(int j=0 ; j<n ; j++)
        {
            if( j>i )
            {
                edge[k].x = i;
                edge[k].y = j;
                edge[k].l = dis(i,j);
                k++;
            }
        }
    }
    sort(edge,edge+n*(n-1)/2,cmp);
}

void kruskal()
{
    int i=0,j=0;
    while( i<n-1 )
    {
        if( judge(edge[j].x,edge[j].y) )
            need += edge[j].l , i++;
        j++;
    }
}

int main()
{
    while(cin>>n,n)
    {
        init();
        kruskal();
        printf("%.3f\n",need );
    }
    return 0;
}
View Code

 

posted @ 2017-10-08 12:58  codeg  阅读(168)  评论(0编辑  收藏  举报