题意:给你一些球体的属性:球心坐标x,y,z 半径 这些球体构成了图,各个球之间的边权等于两个球的距离,求最小生成树。
建好图之后,就用最小生成树做就好。
代码:
#include<iostream> #include<queue> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <math.h> #define INF 0x3f3f3f3f using namespace std; int n; struct node { double x;double y;double z;double r; }point[205]; double map[200][200]; double dis(int i,int j) { double a=point[i].x-point[j].x; double b=point[i].y-point[j].y; double c=point[i].z-point[j].z; return sqrt(a*a+b*b+c*c); } double cross(int i,int j) { double k=point[i].r+point[j].r; double d=dis(i,j); if(d>k) { return d-k; } return 0; } void tree() { double s[200]; int vis[200]; memset(vis,0,sizeof(vis)); for(int i=1;i<n;i++) { s[i]=map[0][i]; } vis[0]=1; int l; double sum=0; for(int i=0;i<n-1;i++)//这个地方一定是n-1,因为总共要找n-1条边。 { double min1=INF; for(int j=0;j<n;j++) { if(!vis[j]&&s[j]<min1) { min1=s[j]; l=j; } } vis[l]=1; sum+=min1; for(int j=0;j<n;j++) { if(!vis[j]&&map[l][j]<s[j]) { s[j]=map[l][j]; } } } printf("%.3f ",sum); } int main() { while(~scanf("%d",&n)&&n) { for(int i=0;i<n;i++) { scanf("%lf%lf%lf%lf",& point[i].x,& point[i].y,&point[i].z,& point[i].r); } memset(map,0,sizeof(map)); for(int i=0;i<n;i++) { for(int j=i+1;j<n;j++) { map[i][j]=map[j][i]=cross(i,j); } } tree(); } return 0; }