poj 2031 给出每个结点的3维坐标 以及结点的半径 (MST)

3维空间中有N个圆球,给出x y z 以及圆球的半径 ,求最小生成树 边的权值为两个圆球间的距离 如果圆球相互接触 则权值为0 求最小的权值和

 

Sample Input

3 //n
10.000 10.000 50.000 10.000 //x y z r
40.000 10.000 50.000 10.000
40.000 40.000 50.000 10.000
2
30.000 30.000 30.000 20.000
40.000 40.000 40.000 20.000
5
5.729 15.143 3.996 25.837
6.013 14.372 4.818 10.671
80.115 63.292 84.477 15.120
64.095 80.924 70.029 14.881
39.472 85.116 71.369 5.553
0
Sample Output

20.000
0.000
73.834

 

Kruskal

  1 # include <iostream>
  2 # include <cstdio>
  3 # include <cstring>
  4 # include <algorithm>
  5 # include <cmath>
  6 # define LL long long
  7 using namespace std ;
  8 
  9 int n ;
 10 const int MAXN=110;//最大点数
 11 const int MAXM=10000;//最大边数
 12 int F[MAXN];//并查集使用
 13 struct Edge
 14 {
 15     int u,v;
 16     double w ;
 17 }edge[MAXM];//存储边的信息,包括起点/终点/权值
 18 
 19 struct poin
 20 {
 21     double x ;
 22     double y ;
 23     double z ;
 24     double r ;
 25 }p[110];
 26 
 27 double dist (double dx ,double dy ,double dz , double r1 , double r2)
 28 {
 29     double t =sqrt(dx*dx +dy*dy + dz*dz) ;
 30     if (t > r1 + r2)
 31         return t-r1-r2 ;
 32     else
 33         return 0.0 ;
 34 }
 35 
 36 int tol;//边数,加边前赋值为0
 37 void addedge(int u,int v,double w)
 38 {
 39 
 40     edge[tol].u=u;
 41     edge[tol].v=v;
 42     edge[tol++].w=w;
 43 }
 44 bool cmp(Edge a,Edge b)
 45 {//排序函数,讲边按照权值从小到大排序
 46     return a.w<b.w;
 47 }
 48 int find(int x)
 49 {
 50     if(F[x]==-1)return x;
 51     else return F[x]=find(F[x]);
 52 }
 53 double Kruskal()//传入点数,返回最小生成树的权值,如果不连通返回-1
 54 {
 55     memset(F,-1,sizeof(F));
 56     sort(edge,edge+tol,cmp);
 57     int cnt=0;//计算加入的边数
 58     double ans=0;
 59     for(int i=0;i<tol;i++)
 60     {
 61         int u=edge[i].u;
 62         int v=edge[i].v;
 63         double w=edge[i].w;
 64         int t1=find(u);
 65         int t2=find(v);
 66         if(t1!=t2)
 67         {
 68             ans+=w;
 69             F[t1]=t2;
 70             cnt++;
 71         }
 72         if(cnt==n-1)break;
 73     }
 74     if(cnt<n-1)return -1;//不连通
 75     else return ans;
 76 }
 77 
 78 int main()
 79 {
 80 
 81    // freopen("in.txt","r",stdin) ;
 82     while (scanf("%d" , &n) != EOF)
 83     {
 84         if (n == 0)
 85             break ;
 86         int i , j;
 87         double dx , dy , dz ;
 88         for (i=0;i<n;i++)
 89             scanf("%lf%lf%lf%lf" , &p[i].x,&p[i].y,&p[i].z,&p[i].r) ;
 90         tol = 0 ; 
 91         for (i = 0 ; i < n ; i++)
 92             for (j = i+1 ; j < n ; j++)
 93             {
 94                 dx = p[i].x - p[j].x ;
 95                 dy = p[i].y - p[j].y ;
 96                 dz = p[i].z - p[j].z ;
 97                 double w = dist(dx,dy,dz,p[i].r,p[j].r) ;
 98                 addedge(i,j,w) ;
 99             }
100         printf("%.3lf\n" ,Kruskal()) ;
101 
102     }
103 
104     return 0 ;
105 }
View Code

 

posted @ 2015-06-15 00:05  __Meng  阅读(205)  评论(0编辑  收藏  举报