Prime_poj2031 Building a Space Station

来源:互联网 发布:圣贝口腔 知乎 编辑:程序博客网 时间:2024/06/05 16:38

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

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


/*Sample Input310.000 10.000 50.000 10.00040.000 10.000 50.000 10.00040.000 40.000 50.000 10.000230.000 30.000 30.000 20.00040.000 40.000 40.000 20.00055.729 15.143 3.996 25.8376.013 14.372 4.818 10.67180.115 63.292 84.477 15.12064.095 80.924 70.029 14.88139.472 85.116 71.369 5.5530Sample Output20.0000.00073.834*/#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<vector>#define MAXN 110#define INF 1000000000using 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;}


原创粉丝点击