版权声明:转载无所谓的。。。 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");//输出
}
}