• POJ2031Building a Space Station


    转载请注明出处:優YoU http://user.qzone.qq.com/289065406/blog/1303311018

     

    大致题意:

    就是给出三维坐标系上的一些球的球心坐标和其半径,搭建通路,使得他们能够相互连通。如果两个球有重叠的部分则算为已连通,无需再搭桥。求搭建通路的最小费用(费用就是边权,就是两个球面之间的距离)。

     

    解题思路:

    不要被三维吓到了,其实就是图论的最小生成树问题

    球心坐标和半径是用来求 两点之间的边权 的,求出边权后,把球看做点,用邻接矩阵存储这个无向图,再求最小生成树,非常简单的水题。

     

    把球A和球B看做无向图图的两个结点,那么

    边权 = AB球面距离 = A球心到B球心的距离   A球半径 – B球半径

     

    边权直接用上面的公式求,接下来再用Prim就能完美AC

    注意若边权<=0,说明两球接触,即已连通,此时边权为0

      1 //Memory Time 
    2 //316K 16MS
    3
    4 #include<iostream>
    5 #include<cmath>
    6 #include<iomanip>
    7 using namespace std;
    8
    9 const double inf=1000.0;
    10 const double eps=1e-10;
    11
    12 typedef class
    13 {
    14 public:
    15 double x,y,z;
    16 double r;
    17 }point;
    18
    19 /*Discuss Precision*/
    20
    21 int EPS(double k)
    22 {
    23 if(fabs(k)<eps)
    24 return 0;
    25 return k>0?1:-1;
    26 }
    27
    28 /*AB之间的距离(权值)*/
    29
    30 double dist(point A,point B)
    31 {
    32 return 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;
    33 } //AB距离是以球面为基准,而不是球心,因此要减去A球和B球的半径
    34
    35 int main(int i,int j)
    36 {
    37 int n;
    38 while(cin>>n)
    39 {
    40 if(n<=0)
    41 break;
    42
    43 /*Initial*/
    44
    45 point* node=new point[n+1];
    46
    47 double w[101][101];
    48 for(i=1;i<=n;i++)
    49 for(j=1;j<=n;j++)
    50 w[i][j]=inf;
    51
    52 /*Input*/
    53
    54 for(i=1;i<=n;i++)
    55 cin>>node[i].x>>node[i].y>>node[i].z>>node[i].r;
    56
    57 for(i=1;i<=n-1;i++)
    58 for(j=i+1;j<=n;j++)
    59 {
    60 double temp=dist(node[i],node[j]);
    61 if(EPS(temp)<=0)
    62 w[i][j]=w[j][i]=0; //两个球接触(相交),则距离(权值)为0
    63 else
    64 w[i][j]=w[j][i]=temp;
    65 }
    66
    67 /*Prim Algorithm*/
    68
    69 bool vist[101]={false};
    70 int s=1;
    71 vist[s]=true;
    72 int fi;
    73 double sum_w=0.0;
    74 for(int count=1;count<n;count++)
    75 {
    76 double min=inf;
    77
    78 for(i=2;i<=n;i++)
    79 if(!vist[i])
    80 if(min>w[s][i])
    81 {
    82 min=w[s][i];
    83 fi=i;
    84 }
    85
    86 sum_w+=w[s][fi];
    87 vist[fi]=true;
    88
    89 for(i=2;i<=n;i++) //新源点s'继承最新合并进来的fi的性质
    90 if(!vist[i]) //以fi到其他点的更短路 取代旧源点s到其他点的权值
    91 if(w[s][i]>w[fi][i])
    92 w[s][i]=w[fi][i];
    93 }
    94
    95 cout<<fixed<<setprecision(3)<<sum_w<<endl;
    96
    97 /*Relax*/
    98
    99 delete node;
    100 }
    101 return 0;
    102 }
  • 相关阅读:
    paip.提升性能---- 网站并发数的总结.txt
    paip.mysql 5.6 安装总结
    UIView上添加了一个按钮和一个单击手势的事件相应,互相不影响的处理方法。。
    paip.mysql备份慢的解决
    paip.输入法编程---词频顺序order by py
    paip.超实用 360浏览器最近频繁奔溃解决流程.
    hdu 4044 GeoDefense (树形dp | 多叉树转二叉树)
    给定一个字符串,仅由a,b,c 3种小写字母组成。
    汉语-词语:心境2
    汉语-词语:休咎
  • 原文地址:https://www.cnblogs.com/lyy289065406/p/2122815.html
Copyright © 2020-2023  润新知