POJ2031 prim
题意:给定一些cell 和 他们的xyz坐标 半径r
求把所有的cell连接起来的最小花费
prim。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<stdio.h> 2 #include<string.h> 3 #include<math.h> 4 #include<queue> 5 using namespace std; 6 const int maxn = 105; 7 const int maxm = 20005; 8 const double inf = 99999999; 9 double mat[ maxn ][ maxn ]; 10 struct node2{ 11 double x,y,z,r; 12 }a[ maxn ]; 13 14 double dist( node2 a,node2 b ){ 15 double sum; 16 sum=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z); 17 return sqrt( sum ); 18 } 19 20 int vis[ maxn ]; 21 double dis[ maxn ]; 22 23 double prim( int n ){ 24 for( int i=0;i<n;i++ ){ 25 vis[ i ]=0; 26 dis[ i ]=mat[ 0 ][ i ]; 27 } 28 vis[ 0 ]=1; 29 double sum=dis[ 0 ]; 30 for( int i=0;i<n;i++ ){ 31 int k; 32 double t=inf; 33 for( int j=0;j<n;j++ ){ 34 if( vis[ j ]==0&&t>dis[ j ] ){ 35 k=j; 36 t=dis[ j ]; 37 } 38 } 39 if( t==inf ) 40 break; 41 vis[ k ]=1; 42 sum+=t; 43 for( int j=0;j<n;j++ ){ 44 if( vis[ j ]==0&&dis[ j ]>mat[ k ][ j ] ){ 45 dis[ j ]=mat[ k ][ j ]; 46 } 47 } 48 } 49 return sum; 50 } 51 52 int main(){ 53 int n; 54 while( scanf("%d",&n),n ){ 55 for( int i=0;i<n;i++ ) 56 scanf("%lf%lf%lf%lf",&a[ i ].x,&a[ i ].y,&a[ i ].z,&a[ i ].r); 57 for( int i=0;i<n;i++ ){ 58 for( int j=i+1;j<n;j++ ){ 59 double tmp=dist( a[i],a[j] ); 60 if( tmp>(a[i].r+a[j].r) ){ 61 mat[i][j]=mat[j][i]=tmp-a[i].r-a[j].r; 62 } 63 else{ 64 mat[i][j]=mat[j][i]=0; 65 }//判断是否加边,加多长的边 66 //printf("mat[%d][%d]:%lf\n",i,j,mat[i][j]); 67 } 68 } 69 double ans=prim( n ); 70 printf("%.3lf\n",ans); 71 } 72 return 0; 73 }
keep moving...