poj2031

来源:互联网 发布:shell执行python文件 编辑:程序博客网 时间:2024/04/30 00:06

题意:给你N个细胞之类的东西,简单理解为球,这是立体的所以球心坐标是x,y,z这样的,然后给你一个球的半径,然后把这些球连接起来,如果两个球之间不想交,那么修建一条道路连起来,如果相交,那么不需要修路,求修路的最短是多少,其实就是最小生成树

思想:不想交距离等于两个点之间距离减去两个球半径,相交距离为0;

这个题除了一晚上bug原来是自己的distance和库函数重名了,改成dist调用就好了

#include<cstdio>

#include<cstring>

#include<cmath>

#include<vector>

#include<queue>

#include<iostream>

#include<algorithm>

#define maxn 120

#define INF 0x3f3f3f3f


using namespace std;


double map[maxn][maxn];

bool vis[maxn];

double d[maxn];

int n;

struct Node

{

    double x,y,z,r;

}node[maxn];

double dist(int i, int j)

{

    double X = node[i].x - node[j].x;

    double Y = node[i].y - node[j].y;

    double Z = node[i].z - node[j].z;

    double dis = sqrt(X*X + Y*Y + Z*Z);

    double len = node[i].r + node[j].r;

    if(dis > len)

        return (dis - len);

    else return 0;

}

void prime()

{

    for(int i = 1; i <= n; i ++)

    {

        d[i] = map[1][i];

        vis[i] = 0;

    }

    for(int i = 1; i <= n; i ++)

    {

        double minx = INF;

        int now;

        for(int j = 1; j <= n; j ++)

        {

            if(!vis[j] && d[j] < minx)

            {

                minx = d[j];

                now = j;

            }


        }

        vis[now] = 1;

        for(int k = 1; k <= n ; k ++)

        {

            if(!vis[k] && d[k] > map[now][k])

                d[k] = map[now][k];

        }

    }

    double sum = 0;

    for(int i = 1; i <= n; i ++)

        sum += d[i];

        printf("%.3f\n",sum);

}

int main()

{

    while(~scanf("%d",&n) && n)

    {

        for(int i = 1; i <= n; i ++)

        scanf("%lf%lf%lf%lf",&node[i].x,&node[i].y,&node[i].z,&node[i].r);

        memset(map,0,sizeof(map));

        for(int i = 1; i <= n; i ++)

            for(int j = i + 1; j <=n; j ++)

        {

            map[i][j] = map[j][i] = dist(i,j);

        }

        prime();

    }


    return 0;

}



0 0
原创粉丝点击