poj 2031 Building a Space Station(prime )
这个题要交c++, 因为prime的返回值错了,改了一会
题目:http://poj.org/problem?id=2031
题意:就是给出三维坐标系上的一些球的球心坐标和其半径,搭建通路,使得他们能够相互连通。如果两个球有重叠的部分则算为已连通,无需再搭桥。求搭建通路的最小费用(费用就是边权,就是两个球面之间的距离
思路:求球之间的距离, 距离小于半径 说明联通 , 距离为0.
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 using namespace std; 6 double const INF=1<<29; 7 double G[110][110]; 8 9 struct node 10 { 11 double x,y,z,r; 12 }p[110]; 13 double prime(int n) 14 { 15 double sum=0.0; 16 int i,j,pos; 17 int v[110]={0}; 18 double d[110],min; 19 for(i=1; i<=n; i++) 20 d[i]=G[1][i]; 21 v[1]=1; 22 for(i=2; i<=n; i++) 23 { 24 min=INF; 25 for(j=1; j<=n; j++) 26 { 27 if(!v[j]&&min>d[j]) 28 { 29 min=d[j]; 30 pos=j; 31 } 32 } 33 sum+=min; 34 v[pos]=1; 35 //printf("%.3lf %.3lf\n",min,sum); 36 for(j=1; j<=n; j++) 37 { 38 if(!v[j]) 39 { 40 if(d[j]>G[pos][j]) 41 d[j]=G[pos][j]; 42 } 43 } 44 //printf("%.3lf %.3lf\n",min,sum); 45 } 46 //printf("%.3lf\n",sum); 47 return sum; 48 } 49 int main() 50 { 51 int n,i,j; 52 double d,sum; 53 while(scanf("%d",&n)&&n) 54 { 55 memset(p,0,sizeof(p)); 56 for(i=1; i<=n; i++) 57 { 58 for(j=1; j<=n; j++) 59 G[i][j]=INF; 60 G[i][i]=0; 61 } 62 for(i=1; i<=n; i++) 63 { 64 scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&p[i].z,&p[i].r); 65 for(j=1; j<i; j++) 66 { 67 d=sqrt((p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y) 68 +(p[i].z-p[j].z)*(p[i].z-p[j].z)); 69 if(d-p[i].r-p[j].r<=0) 70 G[i][j]=G[j][i]=0; 71 else 72 G[i][j]=G[j][i]=d-p[i].r-p[j].r; 73 } 74 } 75 sum=prime(n); 76 printf("%.3lf\n",sum); 77 } 78 return 0; 79 }