zoukankan      html  css  js  c++  java
  • Building a Space Station

    poj2031:http://poj.org/problem?id=2031

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

    题解:其实就是图论的最小生成树问题球心坐标和半径是用来求 两点之间的边权 的,求出边权后,把球看做点,用邻接矩阵存储这个无向图,再求最小生成树,非常简单的水题把球A和球B看做无向图图的两个结点,那么边权 = AB球面距离 = A球心到B球心的距离 –  A球半径 – B球半径 .注意若边权<=0,说明两球接触,即已连通,此时边权为0

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 int n,pa[102],num,cnt;
     8 struct Edge{
     9     int u;
    10     int v;
    11     double w;
    12     bool operator <(const Edge &a)const{
    13         return w<a.w;
    14     }
    15 }edge[5000];
    16 struct Node{
    17     double x;
    18     double y;
    19     double z;
    20     double r;
    21 }node[102];
    22 void UFset(){
    23     for(int i=1;i<=n;i++)
    24      pa[i]=-1;
    25 }  
    26 int Find(int x){
    27     int s;
    28     for(s=x;pa[s]>=0;s=pa[s]);
    29     while(s!=x){
    30         int temp=pa[x];
    31         pa[x]=s;
    32         x=pa[x];
    33     }
    34     return s ;
    35 }
    36 void Union(int R1,int R2){
    37     int r1=Find(R1);
    38     int r2=Find(R2);
    39     int temp=pa[r1]+pa[r2];
    40     if(pa[r1]>pa[r2]){
    41         pa[r1]=r2;
    42         pa[r2]=temp;
    43     }
    44     else{
    45         pa[r2]=r1;
    46         pa[r1]=temp;
    47     }
    48 }
    49 void kruska(){
    50     UFset();
    51     num=0;
    52     double sum=0.0;
    53     for(int i=1;i<cnt;i++){
    54         int u=edge[i].u;
    55         int v=edge[i].v;
    56         if(Find(u)!=Find(v)){
    57             sum+=edge[i].w;
    58             Union(u,v);
    59             num++;
    60         }
    61         if(num>=n-1)break;
    62     }
    63    printf("%.3f
    ",sum);
    64 }
    65 int main(){
    66     while(~scanf("%d",&n)&&n){
    67         for(int i=1;i<=n;i++){
    68             scanf("%lf%lf%lf%lf",&node[i].x,&node[i].y,&node[i].z,&node[i].r);
    69         }
    70         cnt=1;
    71         for(int i=1;i<=n;i++)
    72          for(int j=i+1;j<=n;j++){
    73              double s1=node[i].x-node[j].x;
    74              double s2=node[i].y-node[j].y;
    75              double s3=node[i].z-node[j].z;
    76              double ss=sqrt(s1*s1+s2*s2+s3*s3);
    77              if(ss>node[i].r+node[j].r){
    78               edge[cnt].u=i;edge[cnt].v=j;edge[cnt++].w=ss-node[i].r-node[j].r;    
    79              }
    80            else{
    81                edge[cnt].u=i;edge[cnt].v=j;edge[cnt++].w=0;
    82                  }
    83           }
    84          
    85          sort(edge+1,edge+cnt);
    86          kruska();
    87     }
    88 }
    View Code
  • 相关阅读:
    机器人的运动范围
    矩阵中的路径
    MySql数据库表的基本连接
    Java虚拟机垃圾收集算法
    spring_boot 配置
    js 表格合并单元格
    js数组操作
    前端定位Position属性四个值
    form表单在发送到服务器时候编码方式
    多文件上传CommonsMultipartResolver
  • 原文地址:https://www.cnblogs.com/chujian123/p/3372549.html
Copyright © 2011-2022 走看看