大致题意:
就是给出三维坐标系上的一些球的球心坐标和其半径,搭建通路,使得他们能够相互连通。如果两个球有重叠的部分则算为已连通,无需再搭桥。求搭建通路的最小费用(费用就是边权,就是两个球面之间的距离)。
#include<iostream> #include<cmath> using namespace std; int vis[105],n; double map[105][105],l; double dis(double x1,double y1,double z1,double x2,double y2,double z2) { return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2)); } int main() { double x[105],y[105],z[105],r[105],d; int i,j,min,s; while(scanf("%d",&n)==1 && n) { l=0.0; memset(vis,0,sizeof(vis)); for(i=0;i<n;i++) { cin>>x[i]>>y[i]>>z[i]>>r[i]; } for(i=0;i<n-1;i++) { for(j=i+1;j<n;j++) { d=dis(x[i],y[i],z[i],x[j],y[j],z[j]); if(d>r[i]+r[j]) map[i][j]=map[j][i]=d-r[i]-r[j]; else map[i][j]=map[j][i]=0; } } vis[0]=1; for(i=1;i<n;i++) { min=-1; for(j=1;j<n;j++) { if(!vis[j]) { if(min==-1 || map[0][min]>map[0][j]) min=j; } } l+=map[0][min]; vis[min]=1; for(j=1;j<n;j++) { if(!vis[j]) { if(map[0][j]>map[min][j]) map[0][j]=map[min][j]; } } } printf("%.3lf\n",l); } return 0; }