• 【最小生成树】Building a Space Station POJ


    Building a Space Station POJ - 2031

    题意:

    给定n个球形空间的坐标(x,y,z)以及半径。以下三种情况均可视为空间之间连通:(1)两球之间有重合部分或一个被另一个完全包含在内;(2)两球之间有走廊直接连接;(3)两球之间通过走廊间接连接。走廊建在两个球形空间的表面上。问连通所有空间的走廊的最小长度。

    思路:

    直接套最小生成树的板子。注意建双向边。

    maxn又又又又开小了,只开了500+100这么大,又用这个数来开存边的数组……还好G++会提示RE,这才反应过来

    const int maxn = 50000 + 100;
    
    int fa[maxn];
    int tmp[maxn];
    double x[maxn], y[maxn], z[maxn], r[maxn], w[maxn];
    int u[maxn], v[maxn];
    int n, m;
    
    int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
    bool cmp(int i, int j) {
        return w[i] < w[j];
        //if (w[i] - w[j] < -eps) return true;
        //else return false;
    };
    
    double count(double x1, double y1, double z1, double x2, double y2, double z2,double r1,double r2) {
        double dx = (x1 - x2) * (x1 - x2);
        double dy = (y1 - y2) * (y1 - y2);
        double dz = (z1 - z2) * (z1 - z2);
        double dr = r1 + r2;
        if (sqrt(dx + dy + dz) <= dr) return 0;
        else return sqrt(dx + dy + dz) - dr;
    }
    
    double solve() {
        double ans = 0;
        for (int i = 0; i < maxn; i++) fa[i] = i;
        for (int i = 0; i < m; i++) tmp[i] = i;
        sort(tmp, tmp + m, cmp);
        for (int i = 0; i < m; i++) {
            int e = tmp[i];
            int from = find(u[e]);
            int to = find(v[e]);
            if (from != to) {
                ans += w[e];
                fa[from] = to;
            }
        }
        return ans;
    }
    
    int main()
    {
        //ios::sync_with_stdio(false);
        while (cin >> n && n) {
            m = 0;
            for (int i = 1; i <= n; i++) {
                cin >> x[i] >> y[i] >> z[i] >> r[i];
                for (int j = i; j >= 1; j--) {
                    double cost = count(x[i],y[i],z[i],x[j],y[j],z[j],r[i],r[j]);
                    w[m] = cost; u[m] = i; v[m] = j; m++;
                    w[m] = cost; u[m] = j; v[m] = i; m++;
                }
            }
            printf("%.3f
    ", solve());
        }
        return 0;
    }
    
  • 相关阅读:
    一个Package Load Failed问题的解决方法

    .NET相关的最好东西--全球最新评价
    一年了...
    MSBuild 的简单入门
    开发基于.NET Compact Framework的程序时, 常遇到的问题(2) 为什么在Visual Studio 2003调试程序时不能通过ActiveSync连接PDA
    如何:显示用逗号分隔的项集合(摘自MSDN)
    每日一句(2008.10.8)
    每日一句(2008.10.16)
    男人这辈子
  • 原文地址:https://www.cnblogs.com/streamazure/p/13499874.html
Copyright © 2020-2023  润新知