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 }
时间: 2024-10-06 11:26:55