zoj 1718 poj 2031 Building a Space Station
最小生成树,用了Kruskal算法。POJ上C++能过,G++不能过。。。 算出每两个圆心之间的距离,如果距离小于两半径之和,那么这两个圆心之间的距离直接等于0,否则等于距离-R[i]-R[j]。
#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> using namespace std; const int maxn = 10100; struct abc{ int start, end; double path; }node[maxn]; bool cmp(const abc&a, const abc&b){ return a.path < b.path; } double x[maxn], y[maxn], z[maxn], r[maxn]; int father[maxn]; int find(int x) { if (x != father[x]) father[x] = find(father[x]); return father[x]; } int main() { int n, i, j; while (~scanf("%d", &n)) { if (n == 0) break; int tot = 0; for (i = 1; i <= n; i++) scanf("%lf%lf%lf%lf", &x[i], &y[i], &z[i], &r[i]); for (i = 0; i <= n; i++) father[i] = i; for (i = 1; i <= n; i++) { for (j = i + 1; j <= n; j++) { node[tot].start = i; node[tot].end = j; double tt = sqrt((x[i] - x[j])*(x[i] - x[j]) + (y[i] - y[j])*(y[i] - y[j]) + (z[i] - z[j])*(z[i] - z[j])); if (tt <= r[i] + r[j]) node[tot].path = 0; else node[tot].path = tt - r[i] - r[j]; tot++; } } double ans = 0; sort(node, node + tot, cmp); for (i = 0; i < tot; i++) { int xx = find(node[i].start); int yy = find(node[i].end); if (xx != yy) { father[xx] = yy; ans = ans + node[i].path; } } printf("%.3lf\n", ans); } return 0; }