Building a Space Station (Kruskal算法)

来源:互联网 发布:java开发常见错误 编辑:程序博客网 时间:2024/06/03 19:41

题意:有n个space station,每个space station都是一个球体,已知球的坐标,半径,(x,y,z,r都是double型的)现在要求在space station之间建个通道让所有space station都连接起来,求最小需要建立的通道;注意:如果两个space station相接触或相交就不需要建立通道,即通道为0;很明显求最小生成树;

space station间的距离:(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2)-r1-r2;

这次用Kruskal算法,需要用到并查集;

下面是代码:

#include <stdio.h>#include <stdlib.h>#include <iostream>#include <algorithm>#include <math.h>using namespace std;const int M=105;            //最多100个space station;int uset[M];                //uset数组存该点的祖先;int n, cnt;                 //n是space station的个数;cnt表示边的条数;struct cell{                //struct cell中是space station的坐标和半径;    double x, y, z, r;}q[M];struct edge{               //边的两端点s,e,边权w(通道的长度);    int s, e;    double w;}E[M*M];                   //存边;bool cmp(edge a, edge b){  //sort中的cmp函数,对结构体排序;    return a.w < b.w;}double between(cell a, cell b){//计算两space station通道长度函数;    double dis;    dis=sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z))-a.r-b.r;    if(dis<=0) return 0;     //if 距离小于等于0,说明两space station相交或接触,通道为0;    else return dis;         //否则通道值即为距离值;}int find(int x){             //并查集中find()函数的递归写法;    return x==uset[x]? x : uset[x]=find(uset[x]);}bool link(int x, int y){     //连接两点;    int fx, fy;    fx=find(x);    fy=find(y);    if(fx==fy) return false;    else{        uset[fy]=find(fx);        return true;    }}void Kruskal(){    int i, j, k;    sort(E+1, E+1+cnt, cmp);//对边排序;    for(i=1; i<=n; i++)        uset[i]=i;    double sum=0.0;    int ct=0;    for(i=1; i<=cnt; i++){         //遍历边;        if(link(E[i].s, E[i].e)){  //判断该边的两端点是否已经相连,没连就加上该边,已连就看下一条边;            sum+=E[i].w;            ct++;            if(ct==n-1)            //直到找到n-1条边,跳出循环;                break;        }    }    printf("%.3f\n",sum);    return;}int main(){    while(scanf("%d",&n),n){        int i, j;        cnt=0;        for(i=1; i<=n; i++){            scanf("%lf%lf%lf%lf",&q[i].x,&q[i].y,&q[i].z,&q[i].r);            for(j=1; j<i; j++){                double dis;                dis=between(q[j], q[i]);                E[++cnt].s=j;                E[cnt].e=i;                E[cnt].w=dis;            }        }        Kruskal();    }    return 0;}


原创粉丝点击