关闭

Prime_poj2031 Building a Space Station

标签: structoutputinput算法c
169人阅读 评论(0) 收藏 举报
分类:

题目意思很简单,就是给出一些点,让你搭建通路,使得他们能够相互连通起来,就是把他们连接成一颗树,其中每个点都是一个球,如果两个球有重叠的部分则算为连通。让我们求搭建通路的最小费用(费用和通路长度成正比)。

显然这个是个最小生成树的问题,用那种都行,我用的是Prim算法


/*
Sample Input

3
10.000 10.000 50.000 10.000
40.000 10.000 50.000 10.000
40.000 40.000 50.000 10.000
2
30.000 30.000 30.000 20.000
40.000 40.000 40.000 20.000
5
5.729 15.143 3.996 25.837
6.013 14.372 4.818 10.671
80.115 63.292 84.477 15.120
64.095 80.924 70.029 14.881
39.472 85.116 71.369 5.553
0
Sample Output

20.000
0.000
73.834
*/
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<vector>

#define MAXN 110
#define INF 1000000000
using namespace std;

typedef struct{
    double x, y, z, r;
}sphere;

typedef struct{
    int u, v;
}Edge;

sphere qiuti[MAXN];
double map[MAXN][MAXN];
int visited[MAXN];

vector<int> usedPoint;
vector<Edge> usedEdge;

double cal_dis(sphere &s1, sphere &s2){
    double a = s1.x - s2.x;
    double b = s1.y - s2.y;
    double c = s1.z - s2.z;
    return sqrt(a*a + b*b +c*c) - s1.r - s2.r;
}
double prim(int n){
    memset(visited,0, sizeof(visited));
    usedPoint.clear();
    usedEdge.clear();
    int iflag, jflag,count;
    double minv = INF;
    usedPoint.push_back(0);
    visited[0] = 1; count = 1;
    while(count++ < n){
        minv = INF;
        for(int i = 0; i < usedPoint.size(); i++){
            int tmp = usedPoint[i];
            for(int j = 0; j < n; j++){
                if(!visited[j] && map[tmp][j] < minv){
                    minv = map[tmp][j];
                    iflag = tmp;
                    jflag = j;
                }
            }
        }
        Edge e;
        e.u = iflag;
        e.v = jflag;
        usedPoint.push_back(jflag);
        usedEdge.push_back(e);
        visited[jflag] = 1;
    }

    double sum = 0;
    for(int i = 0; i < usedEdge.size(); i++){
        sum+=map[usedEdge[i].u][usedEdge[i].v];
    }
    return sum;
}
int main(){
    int n;
    while(scanf("%d", &n),n){
        for(int i = 0; i < n; i++){
            scanf("%lf%lf%lf%lf", &qiuti[i].x, &qiuti[i].y, &qiuti[i].z, &qiuti[i].r);
        }
        for(int i = 0; i < n; i++){
            for(int j = i; j< n; j++){
                double dis = cal_dis(qiuti[i], qiuti[j]);
                map[i][j] = map[j][i] = dis > 0 ? dis : 0;
            }
        }
        double len = prim(n);
        printf("%.3f\n", len);
    }
    return 0;
}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:105121次
    • 积分:1862
    • 等级:
    • 排名:千里之外
    • 原创:99篇
    • 转载:12篇
    • 译文:0篇
    • 评论:6条
    最新评论