POJ 2031 Building a Space Station(最小生成树+简单几何)

题意:

在一个三位平面上有几个球体,然后输入数据是给你N个球的球心坐标,以及半径。科学家们想要实现各个球之间的接触,也就是有表面的接触。当然,两个球之间可能会有相交的地方( dis(a,b) <= 0 ),那么这两个球是不用你新建道路来实现想通的。

思路:

求每个球之间球面的距离然后最小生成树就行了。水……

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#include<iomanip>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int maxn=105;
const double eps=1e-8;
const double PI = acos(-1.0);
ll gcd(ll a,ll b)
{
    return b==0?a:gcd(b,a%b);
}
struct node
{
    double x,y,z,r;
};
double dis(node a,node b)
{
    double t=sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z))-a.r-b.r;
    return t>0?t:0;
}
node a[maxn];
int vis[maxn];
double lowc[maxn];
double prim(double cost[][maxn],int n)
{
    double ans=0;
    memset(vis,0,sizeof(vis));
    for(int i=1;i<n;i++)
    {
        lowc[i]=cost[0][i];
    }
    vis[0]=1;
    for(int i=0;i<n-1;i++)
    {
        double minc=inf;
        int p;
        for(int j=0;j<n;j++)
        {
            if(!vis[j]&&minc>lowc[j])
            {
                p=j;
                minc=lowc[j];
            }
        }
        if(minc==inf)   return -1;
        ans+=minc;
        vis[p]=1;
        for(int j=0;j<n;j++)
        {
            if(!vis[j]&&lowc[j]>cost[p][j])
            {
                lowc[j]=cost[p][j];
            }
        }
    }
    return ans;
}
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    int n;
    while(cin>>n&&n)
    {
        for(int i=0;i<n;i++)
        {
            cin>>a[i].x>>a[i].y>>a[i].z>>a[i].r;
        }
        double g[maxn][maxn];
        for(int i=0;i<n;i++)
        {
            for(int j=i+1;j<n;j++)
            {
                if(i==j)    g[i][j]=0;
                else
                {
                    g[i][j]=g[j][i]=dis(a[i],a[j]);
                }
            }
        }
        cout<<fixed<<setprecision(3)<<prim(g,n)<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Dilly__dally/article/details/84581619