POJ 2031(prim+空间坐标)

来源:互联网 发布:淘宝双十一销售排行榜 编辑:程序博客网 时间:2024/06/06 08:42

题意:给出n个点的空间坐标,计算最小生成树。



题读:千万不要害怕。。。看似很长其实就是注意建图就好了。把每个空间节点减去半径就可以看作点来建图。


不过用prim的时候随手就写出了dijkstra。。。尴尬。


#include<iostream>#include<cstdio>#include<cstring>#include<cmath>using namespace std;class Node{public:    double x,y,z;    double r;}edge[110];double gragh[110][110];double dis[110];double ans;int visit[110];int n;double distance(double x1,double y1,double z1,double r1,double x2,double y2,double z2,double r2){    return (sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) + (z1-z2)*(z1-z2))-r1-r2);}void prim(){    for(int i = 1;i <= n; i++)        dis[i] = gragh[1][i];    memset(visit,0,sizeof(visit));    visit[1] = true;    for(int i = 1;i < n; i++){        double Min = 999999999;        int pos;        for(int j = 1;j <= n; j++){            if(visit[j] == 0 && Min > dis[j]){                pos = j;                Min = dis[j];            }        }        ans += dis[pos];        visit[pos] = true;        for(int j = 1;j <= n; j++){            if(visit[j] == 0 && dis[j] > gragh[pos][j]){                dis[j] = gragh[pos][j];            }        }    }}int main(){//    freopen("in.txt","r",stdin);    while(scanf("%d",&n) != EOF){        if(n == 0)            break;        double a,b,c,r;        for(int i = 1;i <= n; i++){            scanf("%lf%lf%lf%lf",&a,&b,&c,&r);            edge[i].x = a;            edge[i].y = b;            edge[i].z = c;            edge[i].r = r;        }        for(int i = 1;i <= n; i++){            for(int j = 1;j <= n; j++){                double d = distance(edge[i].x,edge[i].y,edge[i].z,edge[i].r                                    ,edge[j].x,edge[j].y,edge[j].z,edge[j].r);                if(d > 0){                    gragh[i][j] = d;                    gragh[j][i] = d;                }                else {                    gragh[i][j] = 0;                    gragh[j][i] = 0;                }            }        }        ans = 0;        prim();        printf("%.3f\n",ans);    }    return 0;}


0 0