pku 2031 Building a Space Station 最小生成树+精度控制
http://poj.org/problem?id=2031
题意就是给你n个球的(球心以及半径),然后求最小生成树就欧了,这里的关键部分是对于重复的球的路径长度的处理
#include <iostream> #include <cstring> #include <cstdio> #include <cmath> #define maxn 107 #define inf 999999999 using namespace std; const double eps = 1e-6; struct node { double x,y,z,r; }p[maxn]; double map[100][100],dis[maxn]; bool vt[maxn]; int n; int cmp(double x) { if (x > eps) return 1; else if (x < -eps) return -1; else return 0; } double getlens(int i,int j) { double x = p[i].x - p[j].x; double y = p[i].y - p[j].y; double z = p[i].z - p[j].z; double d = (sqrt(x*x + y*y + z*z) - p[i].r - p[j].r); if (cmp(d) < 0) return 0;//如果有重复的出现,返回0 else return d; } void prim() { int i,j,k; double min; double ans = 0; for (i = 0; i < n; ++i) { vt[i] = false; dis[i] = map[0][i]; } vt[0] = true; for (k = 1; k < n; ++k) { j = 0; min = inf; for (i = 1; i < n; ++i) { if (!vt[i] && min > dis[i]) { j = i; min = dis[i]; } } vt[j] = true; ans += min; for (i = 1; i < n; ++i) { if (!vt[i]) { if (dis[i] > map[i][j]) dis[i] = map[i][j]; } } } printf("%.3lf\n",ans); } int main() { int i,j; while (~scanf("%d",&n)) { if (!n) break; for (i = 0; i < n; ++i) scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&p[i].z,&p[i].r); for (i = 0; i < n; ++i) { for (j = 0; j < n; ++j) { map[i][j] = (i != j)*inf; } } /*for (i = 0; i < n; ++i) { for (j = 0; j < n; ++j) { printf("%.3lf ",map[i][j]); } printf("\n"); }*/ for (i = 0; i < n; ++i) { for (j = i; j < n; ++j) { map[i][j] = map[j][i] = getlens(i,j); } } prim(); } return 0; }