poj2031

来源:互联网 发布:mac系统打不开flash 编辑:程序博客网 时间:2024/05/16 01:49

最小生成树。

边权=AB圆心距离-A半径-B半径。

#include <iostream>
#include <math.h>
#include <iomanip>

using namespace std;

#define eps 1e-8
#define zero(x) (((x)>0?(x):-(x))<eps)
#define MAXN 200
#define inf 1000000000

typedef double elem_t;

struct point3
{
    double x, y, z;
};

struct circle
{
    point3 c;
    double r;
}cir[105];

double dist_r(point3 a, point3 b)
{
    return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y) + (a.z - b.z)*(a.z - b.z));
}

double dist_c(circle a, circle b)
{
    return dist_r(a.c, b.c) - a.r - b.r;
}
elem_t prim(int n, elem_t mat [][MAXN], int* pre)
{
    elem_t min[MAXN], ret = 0;
    int v[MAXN], i, j, k;
    for (i = 0; i < n; i++)
        min[i] = inf, v[i] = 0, pre[i] = -1;
    for (min[j = 0] = 0; j < n; j++){
        for (k = -1, i = 0; i < n; i++)
            if (!v[i] && (k == -1 || min[i] < min[k]))
                k = i;
        for (v[k] = 1, ret += min[k], i = 0; i < n; i++)
            if (!v[i] && mat[k][i] < min[i])
                min[i] = mat[pre[i] = k][i];
    }
    return ret;
}
int main()
{
    int n;
    while (cin >> n && n)
    {
        for (int i = 0; i < n; i++)
        {
            cin >> cir[i].c.x >> cir[i].c.y >> cir[i].c.z >> cir[i].r;
        }
        elem_t mat[MAXN][MAXN];
        for (int i = 0; i < n; i++)
        {
            for (int j = i + 1; j < n; j++)
            {
                double temp = dist_c(cir[i], cir[j]);
                if (zero(temp) || temp < eps)
                {
                    mat[i][j] = mat[j][i] = 0;
                    continue;
                }
                mat[i][j] = mat[j][i] = temp;
            }
        }
        int pre[MAXN];
        cout << fixed << setprecision(3) << prim(n, mat, pre) << endl;
    }
}


用了下代码高亮工具,感觉相当爽歪歪啊~

原创粉丝点击