【POJ】2031 Building a Space Station

题目链接:http://poj.org/problem?id=2031

 

题意:修建太空站每个舱之间的走廊。每个舱都是球体。给出n个舱的三维空间坐标以及球体半径。如果球体之间接触或者相接,就不用修走廊。让你求最短走廊的长度。

 

题解:有点点坑这个题。。改了好久。。这里的存储其实是 $len(a,b) - r_a - r_b$ 求一下这个存储再以Prim求解即可。注意精度。

 

代码:

 

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cmath>
 5 using namespace std;
 6 const int maxn = 105;
 7 const int inf = 0x3f3f3f3f;
 8 const double eps = 1e-10;
 9 double mp[maxn][maxn];
10 double dis[maxn];
11 bool vis[maxn];
12 int n;
13 
14 struct node{
15     double x;
16     double y;
17     double z;
18     double r;
19 };
20 
21 node cir[maxn];
22 
23 double dist(node a,node b){
24     double diss =  (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y) + (a.z -b.z) * (a.z - b.z);
25     return sqrt(diss) - a.r - b.r;
26 }
27 
28 double prim(){
29     double ans = 0 ;
30     int k;
31     double minn ;
32     for(int i = 1 ; i <= n ; i++){
33         dis[i] = inf ;
34         vis[i] = false ;
35     }
36     dis[1] = 0 ;
37     for(int i = 1 ; i <= n ; i++){
38         minn = inf ;
39         k = 0 ;
40         for(int j = 1 ; j <= n ; j++){
41             if(minn > dis[j] && !vis[j]){
42                 minn = dis[j] ;
43                 k = j ;
44             }
45         }
46         if(minn >= inf)
47             return -1 ;
48         ans += minn ;
49         vis[k] = true ;
50         for(int j = 1 ; j <= n ; j++){
51             if(!vis[j] && dis[j] > mp[k][j])
52                 dis[j] = mp[k][j] ;
53         }
54     }
55     return ans ;
56 }
57 
58 int main(){
59     while(cin>>n && n){
60         for(int i = 1; i <= n ;i++){
61             cin>>cir[i].x>>cir[i].y>>cir[i].z>>cir[i].r;        
62         }
63         memset(mp,0,sizeof(mp));
64         for(int i = 1; i < n; i++){
65             for(int j = i+1; j <= n ;j++){
66                 if(dist(cir[i],cir[j]) < eps){
67                     mp[i][j] = mp[j][i] = 0;
68                 }
69                 else{
70                     mp[i][j] = mp[j][i] = dist(cir[i],cir[j]);
71                 }
72             }
73         }
74         /*
75         for(int i = 1; i <= n; i++){
76             for(int j = 1 ; j <= n ;j++){
77                 cout<<mp[i][j]<<" ";
78             }
79             cout<<endl;
80         }*/
81         double ans = prim();
82         if(ans != -1){
83             printf("%.3lf\n",ans);
84         }
85         
86 
87     }
88 
89 
90     return 0;
91 }

 

posted @ 2018-10-07 00:10  甜酒果。  阅读(195)  评论(0编辑  收藏  举报