zoukankan      html  css  js  c++  java
  • POJ 2031(最小生成树Kruskal算法+几何判断)

    题目:给你n,接下来n行每行四个数,空间坐标x ,y,z和半径,求最小生成树

    思路:根据空间坐标半径,求出各个球(可以看成球)重不重叠,重叠就用并查集搞一下,然后数据搞成边的结构体形式,就是道简单最小生成树了

    #include <iostream>
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <map>
    #include <iomanip>
    #include <algorithm>
    #include <queue>
    #include <stack>
    #include <set>
    #include <vector>
    //const int maxn = 1e5+5;
    #define ll long long
    #define lowbit(x) x&(-x)
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
    
    #define MAX INT_MAX
    #define FOR(i,a,b) for( int i = a;i <= b;++i)
    #define bug cout<<"--------------"<<endl
    using namespace std;
    int n,m,tail;
    double ans;
    int pre[11000];
    struct node
    {
        double x,y,z;
    }edge[11000];
    struct hhh
    {
        double x,y,z,r;
    }v[11000];
    double cmp(node a,node b)
    {
        if(a.z!=b.z)
        return a.z<b.z;
        if(a.x!=b.x)
            return a.x<b.x;
        return a.y>b.y;
    }
    int Find(int x)
    {
        if(pre[x]==x) return x;
        return Find(pre[x]);
    }
    double dis(int a,int b)
    {
        double temp=(v[a].x-v[b].x)*(v[a].x-v[b].x)+(v[a].y-v[b].y)*(v[a].y-v[b].y)+(v[a].z-v[b].z)*(v[a].z-v[b].z);
        temp=sqrt(temp);
        if(temp<=v[a].r+v[b].r) return 0;
        return temp-v[a].r-v[b].r;
    
    }
    void besame(int x,int y)
    {
        int fx=Find(x);
        int fy=Find(y);
        if(fx!=fy)  pre[fy]=fx;
    }
    void clearr()
    {
        tail=0;
        ans=0;
        FOR(i,1,n) pre[i]=i;
    }
    int main()
    {
        while(scanf("%d",&n))
        {
            if(n==0) break;
            clearr();
    
            FOR(i,1,n) cin>>v[i].x>>v[i].y>>v[i].z>>v[i].r;
    
            FOR(i,1,n-1)   //小号为头
            {
                FOR(j,i+1,n)
                {
                    if(dis(i,j)==0) besame(i,j);
                    else
                    {
                        edge[++tail].x=i;
                        edge[tail].y=j;
                        edge[tail].z=dis(i,j);
                    }
    
                }
            }
            sort (edge+1,edge+1+tail,cmp);
            FOR(i,1,tail)
            {
                int fx=Find(edge[i].x);
                int fy=Find(edge[i].y);
                if(fx==fy) continue;
                pre[fy]=fx;
                ans+=edge[i].z;
            }
            cout<<fixed<<setprecision(3)<<ans<<endl;
        }
    
    }

      

  • 相关阅读:
    Msql-51CTO笔记
    Elasticsearch 学习第一天
    大数据开发参考资料
    1.docker的安装
    java_根据实体字段中的中文汉字排序
    遍历set集合,进行数据的拼接
    关于integer 和int
    03.linux环境安装mysql8的安装包
    02.linux下面安装jdk8
    01.VMware15.5下安装Centos7
  • 原文地址:https://www.cnblogs.com/jrfr/p/11291961.html
Copyright © 2011-2022 走看看