传送门
解法:
我们可以通过枚举判断点与点以及上下表面是否联通
并存入并查集
最后判断上下表面是否在同一集合中
代码:
#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;
}