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;

}

 

你可能感兴趣的:(Build)