题目链接:http://poj.org/problem?id=2031
求出任意两点之间的距离减去两个点的半径。
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=110; 7 int n; 8 int f[maxn]; 9 struct node 10 { 11 double x,y,z; 12 double r; 13 }p[maxn]; 14 15 struct edge 16 { 17 int u,v; 18 double w; 19 bool operator < (const edge &a) 20 { 21 return w<a.w; 22 } 23 }e[100010]; //不知道要开多大! 24 25 double getdis(int i,int j) 26 { 27 double dx=p[i].x-p[j].x; 28 double dy=p[i].y-p[j].y; 29 double dz=p[i].z-p[j].z; 30 return sqrt(dx*dx+dy*dy+dz*dz)-p[i].r-p[j].r; 31 } 32 33 void init() 34 { 35 for(int i=0;i<n;i++) 36 f[i]=i; 37 } 38 39 int gf(int a) 40 { 41 return a==f[a]?a:f[a]=gf(f[a]); 42 } 43 44 void uni(int a,int b) 45 { 46 int pa=gf(a); 47 int pb=gf(b); 48 f[pb]=pa; 49 } 50 51 int main() 52 { 53 while(scanf("%d",&n)&&n) 54 { 55 init(); 56 for(int i=0;i<n;i++) 57 { 58 scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&p[i].z,&p[i].r); 59 } 60 int cnt=0; 61 for(int i=0;i<n;i++) 62 for(int j=i+1;j<n;j++) 63 { 64 e[cnt].u=i; 65 e[cnt].v=j; 66 e[cnt].w=getdis(i,j); 67 cnt++; 68 } 69 double ans=0; 70 sort(e,e+cnt); 71 for(int i=0;i<cnt;i++) 72 { 73 if(e[i].w<=0) uni(e[i].u,e[i].v); 74 else if(gf(e[i].u)!=gf(e[i].v)) {ans+=e[i].w; uni(e[i].u,e[i].v);} 75 } 76 printf("%.3f ",ans); 77 } 78 }