码迷,mamicode.com
首页 > 其他好文 > 详细

POJ - 2031 Building a Space Station (prim)

时间:2019-08-05 14:22:10      阅读:92      评论:0      收藏:0      [点我收藏+]

标签:ios   printf   main   second   div   max   坐标   注意   最小   

题意:给出球形空间站数目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\n",ans);//注意:在G++下精度要用%f来输出 如果用 %lf输出则会wa
    }
}

 

POJ - 2031 Building a Space Station (prim)

标签:ios   printf   main   second   div   max   坐标   注意   最小   

原文地址:https://www.cnblogs.com/Tianwell/p/11302317.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!