POJ 2031Building a Space Station

来源:互联网 发布:软件测试简历范文 编辑:程序博客网 时间:2024/06/18 01:31
题意:就是给出三维坐标系上的一些球的球心坐标和其半径,搭建通路,使得他们能够相互连通。如果两个球有重叠的部分则算为已连通,无需再搭桥。求搭建通路的最小费用,最小生成树板子题,细心处理数据即可;
#include<algorithm>#include<iostream>#include<queue>#include<stack>#include<vector>#include<map>#include<set>#include<cstring>#include<string>#include<cstdio>#include<cmath>using namespace std;typedef struct node{int x;int y;double date;}node;typedef struct list{double a;double b;double c;double d;}list;bool cmp(node e,node r){return e.date<r.date;}int first[115];int next[115];void csh(int m){for(int i=1;i<=m;i++){first[i]=i;next[i]=1;}return ;} int find(int x){if(x==first[x])  return x;else{x=first[x];return find(x);}}void hebin(int x,int y){x=find(x);y=find(y);if(x==y) return ;else{if(next[x]>next[y]){first[y]=x;}else{first[x]=y;if(next[x]==next[y]){next[y]++;}}}return ;}list aa[115];node vulue[20010];int main(){int m;while(scanf("%d",&m)==1&&m!=0){for(int i=1;i<=m;i++){scanf("%lf %lf %lf %lf",&aa[i].a,&aa[i].b,&aa[i].c,&aa[i].d);}int ans=0;int u=0;csh(m);for(int i=1;i<m;i++){for(int j=i+1;j<=m;j++){double t;t=1.0*sqrt((aa[j].a-aa[i].a)*(aa[j].a-aa[i].a)+(aa[j].b-aa[i].b)*(aa[j].b-aa[i].b)+(aa[j].c-aa[i].c)*(aa[j].c-aa[i].c))-aa[i].d-aa[j].d;if(t<=0){if(find(i)!=find(j)){ans++;hebin(i,j);}}else{u++;vulue[u].x=i;vulue[u].y=j;vulue[u].date=t;}}}sort(vulue+1,vulue+u+1,cmp);double sum=0;for(int i=1;i<=u;i++){if(find(vulue[i].x)!=find(vulue[i].y)){ans++;sum+=vulue[i].date;hebin(vulue[i].x,vulue[i].y);if(ans==(m-1)){break;}}}printf("%.3lf\n",sum);}return 0;}