zoukankan      html  css  js  c++  java
  • Prim POJ 2031 Building a Space Station

    题目传送门

    题意:给出n个三维空间的球体,球体是以圆心坐标+半径来表示的,要求在球面上建桥使所有的球联通,求联通所建桥的最小长度。

    分析:若两点距离大于两半径和的长度,那么距离就是两点距离 - 半径和,否则为0,Prim写错了,算法没有完全理解

    /************************************************
    * Author        :Running_Time
    * Created Time  :2015/10/25 12:00:48
    * File Name     :POJ_2031.cpp
     ************************************************/
    
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <queue>
    #include <deque>
    #include <stack>
    #include <list>
    #include <map>
    #include <set>
    #include <bitset>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    #define lson l, mid, rt << 1
    #define rson mid + 1, r, rt << 1 | 1
    typedef long long ll;
    const int N = 1e2 + 10;
    const int E = N * N;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e9 + 7;
    const double EPS = 1e-10;
    
    bool vis[N];
    double d[N];
    int head[N];
    int n, m, e;
    int dcmp(double x)  {       //三态函数,减少精度问题 
        if (fabs (x) < EPS) return 0; 
        else    return x < 0 ? -1 : 1; 
    } 
    struct Point    {
        double x, y, z, a;
        Point () {}
        Point (double x, double y, double z, double a) : x (x), y (y), z (z), a (a) {}
        Point operator - (const Point &r) const {       //向量减法 
            return Point (x - r.x, y - r.y, z - r.z, 0); 
        } 
    };
    typedef Point Vector;       //向量的定义 
    Point read_point(void)   {      //点的读入 
        double x, y, z, r; 
        scanf ("%lf%lf%lf%lf", &x, &y, &z, &r); 
        return Point (x, y, z, r); 
    } 
    double dot(Vector A, Vector B)  {       //向量点积 
        return A.x * B.x + A.y * B.y + A.z * B.z; 
    } 
    double length(Vector A) {       //向量长度,点积 
        return sqrt (dot (A, A)); 
    } 
    
    struct Edge {
        int v, nex;
        double w;
        Edge () {}
        Edge (int v, double w, int nex) : v (v), w (w), nex (nex) {}
        bool operator < (const Edge &r) const   {
            return w > r.w;
        }
    }edge[E];
    
    void init(void) {
        memset (head, -1, sizeof (head));
        e = 0;
    }
    
    void add_edge(int u, int v, double w)   {
        edge[e] = Edge (v, w, head[u]);
        head[u] = e++;
    }
    
    double Prim(int s) {
        memset (vis, false, sizeof (vis));
        for (int i=0; i<n; ++i) d[i] = 1e9;
        priority_queue<Edge> Q;
        for (int i=head[s]; ~i; i=edge[i].nex)  {
            int v = edge[i].v;  double w = edge[i].w;
            if (d[v] > w)   {
                d[v] = w;   Q.push (Edge (v, d[v], 0));
            }
        }
        vis[s] = true;  d[s] = 0;
        double ret = 0;
        while (!Q.empty ()) {
            int u = Q.top ().v; Q.pop ();
            if (vis[u]) continue;
            vis[u] = true;  ret += d[u];
            for (int i=head[u]; ~i; i=edge[i].nex)  {
                int v = edge[i].v;  double w = edge[i].w;
                if (!vis[v] && d[v] > w)   {
                    d[v] = w;    Q.push (Edge (v, d[v], 0));
                }
            }
        }
        return ret;
    }
    
    Point p[N];
    int main(void)    {
        while (scanf ("%d", &n) == 1)   {
            if (!n) break;
            for (int i=0; i<n; ++i) {
                p[i] = read_point ();
            }
            init ();
            for (int i=0; i<n; ++i) {
                for (int j=i+1; j<n; ++j)   {
                    double dis = length (p[i] - p[j]);
                    double len = p[i].a + p[j].a;
                    if (dcmp (dis - len) <= 0)   {
                        add_edge (i, j, 0);
                        add_edge (j, i, 0);
                    }
                    else    {
                        add_edge (i, j, dis - len);
                        add_edge (j, i, dis - len);
                    }
                }
            }
            printf ("%.3f
    ", Prim (0));
        }
    
        return 0;
    }
    
    编译人生,运行世界!
  • 相关阅读:
    1-1-折纸问题
    调整数组顺序使奇数位于偶数前面
    在O(1)时间删除链表结点
    打印1到最大的n位数
    数值的整数次方
    二进制中1的个数
    变态跳台阶
    旋转数组的最小数字
    用两个栈实现队列
    Swift学习笔记(5):集合类型
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4908682.html
Copyright © 2011-2022 走看看