zoukankan      html  css  js  c++  java
  • POJ

    题意:给出球形空间站数目N,以及各个空间站的三维坐标x,y,z 以及 半径r ,求将所有空间站连接的最小cost (cost就等于空间站之间的距离) 如果接触,包含,或者相交则不需要搭建桥

    思路:还是一道最小生成树的题目,我们先记录每个空间站的信息,然后将所有空间站两两相连接,如果 如果接触,包含,或者相交 我们就把cost 置为1 ,否则就用距离半径之和。

    把每个空间站用一个标号表示,然后记录到 向前星中 。 用prim算法 去找最小生成树即可 。

    还有一点要注意的是,最后结过的输出:G++下要使用%f而不能使用%lf

    完整代码;

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    #include <vector>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    const int maxn = 1000;
    const int maxm = 1e5;
    int n,m;
    double ans;
    typedef pair<double,int> pii;
    struct Egde{
        int u,v,next;
        double w;
    }edge[maxm];
    struct node{
        double x,y,z,r;
    }space[maxn];
    struct cmp{
        bool operator () (pii a, pii b){
            return a.first > b.first;
        }
    };
    int head[maxn];
    int vis[maxn];
    double dist[maxn];
    int top;
    void init(){
        memset(head,-1,sizeof(head));
        memset(vis,0,sizeof(vis));
        memset(dist,-1,sizeof(dist));
        top = 0;
        ans = 0;
    }
    void add(int u,int v,double w){
        int i;//更新最小边权值 
        for(i=head[u]; ~i; i=edge[i].next){
            if(edge[i].v == v){
                if(edge[i].w > w) edge[i].w = w;
                return ;
            }    
        }
        edge[top].u = u;
        edge[top].v = v;
        edge[top].w = w;
        edge[top].next = head[u];
        head[u] = top++;
    }
    void prim(int s){
        int i;
        priority_queue<pii,vector<pii>, cmp>q;
        vis[s] = 1;
        dist[s] = 0;
        for(i = head[s];~i;i = edge[i].next){
            int v = edge[i].v;
            dist[v] = edge[i].w;
            q.push(make_pair(dist[v],v));
        }
        while(!q.empty()){
            pii t = q.top();
            q.pop();
            if(vis[t.second]) continue;
            ans += t.first;
            vis[t.second] = 1;
            
            for(i = head[t.second]; ~i;i = edge[i].next){
            int v = edge[i].v;
            if(!vis[v]&&(dist[v]>edge[i].w)||dist[v] == -1){
                dist[v] = edge[i].w;
                q.push(make_pair(dist[v],v));
                }
            }        
        }
        
    }
    double getDist(int i,int j){
        double sX = (space[i].x-space[j].x)*(space[i].x-space[j].x);
        double sY = (space[i].y-space[j].y)*(space[i].y-space[j].y);
        double sZ = (space[i].z-space[j].z)*(space[i].z-space[j].z);
        double dis =  sqrt(sX+sY+sZ);
        if(dis<=(space[i].r+space[j].r)) return 0.00;
        else return dis-(space[i].r+space[j].r); 
    }
    int main(){
        while(cin>>n&&n){
    //        cin>>m;
            init();
            for(int i=0; i<n;i++){
                cin>>space[i].x>>space[i].y>>space[i].z>>space[i].r;
            }
            for(int i=0; i<n;i++){
                for(int j=0;j<n;j++){
                    if(i==j) continue;
                    add(i,j,getDist(i,j));
                    add(j,i,getDist(j,i));
                }
            } 
            prim(0); 
            printf("%.3f
    ",ans);//注意:在G++下精度要用%f来输出 如果用 %lf输出则会wa
        }
    }
  • 相关阅读:
    谈谈入职新公司1月的体会
    来点高逼格的,使用前端Sendmessage实现SSO
    2019做的第一个艰难决定
    Golang中设置函数默认参数的优雅实现
    linux系统shell基础知识入门二
    在AWS中自定义Credential Provider实现Client连接
    linux系统shell基础知识入门
    初学者学习golang可能遇到的坑
    【Menu】 目录索引
    rsync 服务介绍及相关实验
  • 原文地址:https://www.cnblogs.com/Tianwell/p/11302317.html
Copyright © 2011-2022 走看看