POJ 2031Building a Space Station
题意:就是给出三维坐标系上的一些球的球心坐标和其半径,搭建通路,使得他们能够相互连通。如果两个球有重叠的部分则算为已连通,无需再搭桥。求搭建通路的最小费用,最小生成树板子题,细心处理数据即可;
#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; }