Building a Space Station

poj2031:http://poj.org/problem?id=2031

题意:就是给出三维坐标系上的一些球的球心坐标和其半径,搭建通路,使得他们能够相互连通。如果两个球有重叠的部分则算为已连通,无需再搭桥。求搭建通路的最小费用(费用就是边权,就是两个球面之间的距离)。

题解:其实就是图论的最小生成树问题球心坐标和半径是用来求 两点之间的边权 的,求出边权后,把球看做点,用邻接矩阵存储这个无向图,再求最小生成树,非常简单的水题把球A和球B看做无向图图的两个结点,那么边权 = AB球面距离 = A球心到B球心的距离 –  A球半径 – B球半径 .注意若边权<=0,说明两球接触,即已连通,此时边权为0

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 int n,pa[102],num,cnt;
 8 struct Edge{
 9     int u;
10     int v;
11     double w;
12     bool operator <(const Edge &a)const{
13         return w<a.w;
14     }
15 }edge[5000];
16 struct Node{
17     double x;
18     double y;
19     double z;
20     double r;
21 }node[102];
22 void UFset(){
23     for(int i=1;i<=n;i++)
24      pa[i]=-1;
25 }  
26 int Find(int x){
27     int s;
28     for(s=x;pa[s]>=0;s=pa[s]);
29     while(s!=x){
30         int temp=pa[x];
31         pa[x]=s;
32         x=pa[x];
33     }
34     return s ;
35 }
36 void Union(int R1,int R2){
37     int r1=Find(R1);
38     int r2=Find(R2);
39     int temp=pa[r1]+pa[r2];
40     if(pa[r1]>pa[r2]){
41         pa[r1]=r2;
42         pa[r2]=temp;
43     }
44     else{
45         pa[r2]=r1;
46         pa[r1]=temp;
47     }
48 }
49 void kruska(){
50     UFset();
51     num=0;
52     double sum=0.0;
53     for(int i=1;i<cnt;i++){
54         int u=edge[i].u;
55         int v=edge[i].v;
56         if(Find(u)!=Find(v)){
57             sum+=edge[i].w;
58             Union(u,v);
59             num++;
60         }
61         if(num>=n-1)break;
62     }
63    printf("%.3f\n",sum);
64 }
65 int main(){
66     while(~scanf("%d",&n)&&n){
67         for(int i=1;i<=n;i++){
68             scanf("%lf%lf%lf%lf",&node[i].x,&node[i].y,&node[i].z,&node[i].r);
69         }
70         cnt=1;
71         for(int i=1;i<=n;i++)
72          for(int j=i+1;j<=n;j++){
73              double s1=node[i].x-node[j].x;
74              double s2=node[i].y-node[j].y;
75              double s3=node[i].z-node[j].z;
76              double ss=sqrt(s1*s1+s2*s2+s3*s3);
77              if(ss>node[i].r+node[j].r){
78               edge[cnt].u=i;edge[cnt].v=j;edge[cnt++].w=ss-node[i].r-node[j].r;    
79              }
80            else{
81                edge[cnt].u=i;edge[cnt].v=j;edge[cnt++].w=0;
82                  }
83           }
84          
85          sort(edge+1,edge+cnt);
86          kruska();
87     }
88 }
View Code

 

posted on 2013-10-16 16:58  天依蓝  阅读(118)  评论(0编辑  收藏  举报

导航