zoukankan      html  css  js  c++  java
  • poj 2031 Building a Space Station(prim)

    颓废了几天,开始努力~

    题意:给出N个球体的球新坐标以及球的半径,让你求出连接这N个球的最短的隧道距离,其中相接触和相覆盖的两个球之间不由隧道。

    思路:最小生成树,刚开始的想法是kruskal,但是看了discuss里的讨论,说prim更快些,所以就用了prim,不用排序的确更容易些。

    代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <math.h>
    #define maxm 105
    #define INF 0xffff
    using namespace std ;
    
    struct node
    {
        double x , y , z ;
        double rad ;
    }p[maxm] ;
    
    int f[maxm] ;
    double dis[maxm] ;
    
    double prim ( int a , int b )
    {
        if ( p[a].x == p[b].x && p[a].y == p[b].y && p[a].z == p[b].y && p[a].rad == p[b].rad )
        return 0.0 ;
        else
        {
            double xx = p[a].x - p[b].x ;
            double yy = p[a].y - p[b].y ;
            double zz = p[a].z - p[b].z ;
            double len = sqrt ( ( xx * xx ) + ( yy * yy ) + ( zz * zz )) ;
            if ( ( len- p[a].rad - p[b].rad ) <= 0.000001)
            return 0.0 ;
            else
            return ( len - p[a].rad - p[b].rad )  ;
        }
        return 0.0 ;
    }
    
    int main()
    {
        int i , j , k , n ;
        double s , len ;
    
        while ( scanf ( "%d" , &n ) , n)
        {
            memset( f , 0 , sizeof ( f )) ;
            for ( i = 0 ; i < n ; i++ )
            {
                scanf ( "%lf%lf%lf%lf" , &p[i].x , &p[i].y , &p[i].z , &p[i].rad ) ;
                dis[i] = 1000.0 ;
            }
            for ( i = 1 ; i < n ; i++ )
            {
                dis[i] = prim ( 0 , i ) ;
            }
            s = 0.0 ;
            f[0] = 1 ;
            for ( i = 1 ; i <  n ; i++ )
            {
                k = -1 ;
                double minn = INF * 1.0;
                for ( j = 1 ; j < n ; j++ )
                {
                    if ( dis[j] < minn && !f[j] )
                    {
                        k = j ;
                        minn = dis[j] ;
                    }
                }
                if ( k > 0 )
                {
                    f[k] = 1 ;
                    s += minn ;
                }
                for ( j = 0 ; j < n ; j++ )
                {
                    double len =prim ( k , j ) ;
                    if ( len < dis[j] && !f[j] )
                    {
                        dis[j] = len ;
                    }
                }
            }
            printf ( "%.3lf\n" , s );
        }
        return 0 ;
    }
  • 相关阅读:
    xtrabackup详细用法
    CentOS国内YUM源及配置
    CentOS7系统配置国内yum源和epel源
    Zabbix的定期备份
    Zabbix的邮件告警
    石头剪刀布---组合数取模,数论
    组合数取模介绍----Lucas定理介绍
    乘法逆元
    费马小定理
    欧几里德与扩展欧几里德算法----数论
  • 原文地址:https://www.cnblogs.com/misty1/p/2589959.html
Copyright © 2011-2022 走看看