【并查集】洛谷P3958 奶酪

版权声明:转载无所谓的。。。 https://blog.csdn.net/xuxiayang/article/details/82690599

链接

https://www.luogu.org/problemnew/show/P3958


大意

给定一些洞,求能否从上面走到下面


思路

若两个洞相交或相切,则用并查集将它们合并在一起,将顶部和底部当作一个无穷扁的圆,判断顶部和底部是否相连即可


代码

#include<cstdio>
#include<cmath>
#define r(i,a,b) for(register int i=a;i<=b;i++)
using namespace std;int f[1002],n,h,r,t;
long long x[1002],y[1002],z[1002];
inline int find(register int x){return x==f[x]?x:f[x]=find(f[x]);}
inline void merge(register int x,register int y){f[find(x)]=find(y);return;}
inline long long read()
{
    long long f=0;int d=1;char c;
    while(c=getchar(),c<48||c>57) if(c=='-')d=-1;f=(f<<3)+(f<<1)+c-48;
    while(c=getchar(),c>47&&c<58) f=(f<<3)+(f<<1)+c-48;
    return d*f;
}
inline long long power(register long long x){return x*x;}
signed main()
{
    t=read();
    while(t--)
    {
        n=read();h=read();r=read();
        r(i,0,n+1) f[i]=i;//并查集初始化
        r(i,1,n) 
        {
            x[i]=read();y[i]=read();z[i]=read();
            if(z[i]<=r) merge(0,i);
            if(z[i]+r>=h) merge(i,n+1);//输入+判断是否连接
        }
        r(i,1,n-1) r(j,i+1,n)
        if(sqrt(power(x[i]-x[j])+power(y[i]-y[j])+power(z[i]-z[j]))<=r*2) merge(i,j);//判断是否连接
        if(find(0)==find(n+1)) printf("Yes\n");else printf("No\n");//输出
    }
}

猜你喜欢

转载自blog.csdn.net/xuxiayang/article/details/82690599