首页 > 代码库 > poj2031 Building a Space Station 三维空间的最小生成树

poj2031 Building a Space Station 三维空间的最小生成树

题目链接:

2031

http://write.blog.csdn.net/postedit?ref=toolbar




题意:

在三维空间中有N个球形空间站,给出每个空间站的三维坐标x,y,z 和半径.其中空间站之间可能存在相交,包含,相离等情况。如果非相离则两空间站的距离为0。求连同所有空间站的最小生成树。




题解:

三维构图两空间站的距离等于两圆心距离减去两圆的半径 如果距离小于0,则距离为0

在套kruskal模板即可




代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
struct node
{
    int u,v;
    double w;
} edge[10005];
double map[105][4],ans;
int fa[105];
int m,s;
int cmp(node a,node b)
{
    return a.w<b.w;
}
int find(int x)
{
    int d=x,t;
    while(fa[d]>=0)
        d=fa[d];
    while(x!=d)       //压缩路径
    {
        t=fa[x];
        fa[x]=d;
        x=t;
    }
    return d;
}
void Kruskal()
{
    int r1,i,j,r2,n=0,ss;
    for(i=0; i<s; i++)
    {
        r1=find(edge[i].u),r2=find(edge[i].v);
        if(r1!=r2)
        {
            n++;
            ss=fa[r1]+fa[r2];
            ans+=edge[i].w;
            if(fa[r1]<fa[r2])
                fa[r1]=ss,fa[r2]=r1;
            else
                fa[r1]=r2,fa[r2]=ss;
        }
        if(n==m-1)
            break;
    }
    return;
}
int main()
{
    int i,j;
    double weight;
    while(scanf("%d",&m)&&m)
    {
        ans=s=0;
        memset(fa,-1,sizeof(fa));
        for(i=1; i<=m; i++)
        {
            scanf("%lf%lf%lf%lf",&map[i][0],&map[i][1],&map[i][2],&map[i][3]);
            for(j=1; j<i; j++)
            {
                edge[s].u=j,edge[s].v=i;
                weight=sqrt(pow(map[i][0]-map[j][0],2)+pow(map[i][1]-map[j][1],2)+pow(map[i][2]-map[j][2],2));
                if(weight>map[i][3]+map[j][3])              //距离
                    edge[s++].w=weight-map[i][3]-map[j][3];
                else
                    edge[s++].w=0;
            }
        }
        sort(edge,edge+s,cmp);
        Kruskal();
        printf("%.3lf\n",ans);
    }
    return 0;
}



poj2031 Building a Space Station 三维空间的最小生成树