POJ Building a Space Station 2031 (最小生成树+三维空间)

来源:互联网 发布:电脑海报设计软件 编辑:程序博客网 时间:2024/06/04 21:14

大意:在空间中给定球的坐标,和棋半径,问所以球之间都可达并且权值和最小(球之间有重合的部分)。

思路:直接最小生成树。

#include<map>#include<queue>#include<cmath>#include<cstdio>#include<stack>#include<iostream>#include<cstring>#include<algorithm>#define inf 0x3f3f3f3f#define eps 1e-8#define mod 1000000007#define ls l,mid,rt<<1#define rs mid+1,rt,rt<<1|1#define LL __int64using namespace std;struct node{    double x,y,z,r;}q[110];double dis[110],mp[110][110];bool vis[110];int n;double so(int a,int b){    double tmp = sqrt( (q[a].x-q[b].x)*(q[a].x-q[b].x)+(q[a].y-q[b].y)*(q[a].y-q[b].y)+(q[a].z-q[b].z)*(q[a].z-q[b].z) );    if( (q[a].r+q[b].r)-tmp >= eps )        return 0;    else        return tmp -= (q[a].r+q[b].r);}void prim(){    int i,j;    //cout<<"**"<<endl;    for(int i = 0;i < n;++ i)        dis[i] = mp[0][i];    dis[0] = 0;    memset(vis,false,sizeof(vis));    vis[0] = true;    double ma = inf;    int pos;    double ans=0;    for(i = 0;i < n-1;++ i){        ma = inf;        for(j = 0 ;j < n;++ j ){            if(!vis[j]&&dis[j] < ma ){                pos = j;                ma = dis[j];            }        }        vis[pos] = true;        ans += ma;        for(j = 0;j <n;++j){            if(!vis[j] && dis[j] >mp[pos][j] )               dis[j] = mp[pos][j];        }    }    printf("%.3f\n",ans);}int main(){    int m,i,j,k;    while(~scanf("%d",&n)&&n){        for(i = 0;i < n;++ i){            scanf("%lf%lf%lf%lf",&q[i].x,&q[i].y,&q[i].z,&q[i].r);        }        for(i = 0;i < n;++ i ){            mp[i][i] = 1.0;            for(j = i + 1;j < n;++ j){                mp[i][j] = mp[j][i] = so(i,j);            }        }        prim();    }    return 0;}
0 0
原创粉丝点击