奶酪

传送门

解法:

我们可以通过枚举判断点与点以及上下表面是否联通

并存入并查集

最后判断上下表面是否在同一集合中

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<map>
#define inf 2000000000
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define dwn(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
typedef long long ll;
int T;
int n,h,r;
int par[1010];
struct node
{
    int x,y,z;
}a[1010];
inline void init(int n)
{
    for(int i=0;i<=n;i++)
        par[i]=i;
}
int get(int x)
{
    if(par[x]==x) return x;
    return par[x]=get(par[x]);
}
inline bool same(int x,int y)
{
    return get(x)==get(y);
}
inline void unite(int x,int y)
{
    x=get(x),y=get(y);
    par[x]=y;
}
inline double dist(int i,int j)
{
    return sqrt(1ll*(a[i].x-a[j].x)*(a[i].x-a[j].x)+1ll*(a[i].y-a[j].y)*(a[i].y-a[j].y)+1ll*(a[i].z-a[j].z)*(a[i].z-a[j].z));
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&n,&h,&r);
        init(n+1);
        rep(i,1,n)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            a[i].x=x,a[i].y=y,a[i].z=z;
            if(z-r<=0) unite(i,0);
            if(z+r>=h) unite(i,n+1);
            rep(j,1,i-1)
            {
                if(dist(i,j)<=2*r)
                    unite(i,j);
            }
        }
        if(same(0,n+1)) printf("Yes
");
        else printf("No
");
    }
    return 0;
}

原文地址:https://www.cnblogs.com/MYsBlogs/p/10988047.html