POJ 2031 (Kruskal minimum spanning tree algorithm determines the geometric +)

Title: Here n, the next four lines each number n, the spatial coordinates x, y, z and radius, minimum spanning tree

Ideas: The radius of the space coordinates, obtains respective balls (ball can be seen) weight not overlap, overlap with disjoint-set to look out, and the data structure into an edge of the form, the minimum spanning tree is simply channel

#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;
    }

}

 

  

Guess you like

Origin www.cnblogs.com/jrfr/p/11291961.html
Recommended