cpp
//本题dfs没错,开的N的范围是错的
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e3+10;//这题题目n的最大值为1e3
ll int t,n,h,r,p;
ll int vis[N],con[N][N];
ll int high[N],low[N];//因为题目所给的是圆心的坐标,还有半径,
//而我要计算的是是否能到上表面和下表面
bool flag=0;//用flag来判断是否有一组解满足要求
struct ty{
ll int x,y,z;
}a[N];
int dfs(int x)//x是指的是第x个点
{
if(high[x] >= h) //保证有一组解能从下面到上面即可
{
flag=1;
cout<<"Yes"<<endl;
return 1;//找到返回1
}
for(int i=1;i<=n;i++) //错误点1:没想到遍历每个点的情况
{
if(vis[i]==0 && con[x][i]==1)
{
vis[i]=1;
dfs(i);
// if(dfs(i)) return 1;
// vis[i]=0; //错误点3;这题如果回溯那么就会超时,而且这题的确不需要回溯
}
}
return 0;
}
int dis(int i,int j)//为了防止开平方后的精度误差,直接比较两边的距离的平方
{
return (a[i].x-a[j].x) * (a[i].x-a[j].x) + (a[i].y-a[j].y) * (a[i].y-a[j].y)
+ (a[i].z-a[j].z) * (a[i].z-a[j].z) <=4 * r * r;
}
int main()
{
cin>>t;
while(t--)
{
memset(vis,0,sizeof(vis));
memset(con,0,sizeof(con));
memset(a,0,sizeof(a));
memset(low,0,sizeof(low));
memset(high,0,sizeof(high));
cin>>n>>h>>r;
flag=0;
for(int i=1;i<=n;i++)
{
cin>>a[i].x>>a[i].y>>a[i].z;
high[i]=a[i].z+r;
low[i]=a[i].z-r;
}
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)//边读边计算距离,判断两个洞是否可以连通
{
int t=dis(i,j);//计算两个点之间的距离
// cout<<"距离为"<<t<<endl;
if(t==1) con[i][j]=con[j][i]=1;
}
for(int i=1;i<=n;i++)
{
if(low[i] <= 0)
{
vis[i] = 1;
// p=dfs(i);//错误点2:这样子输出相当于只判断了最一个点的情况
dfs(i);
if(flag) break;
}
}
// if(p==1) cout<<"Yes"<<endl;
// else cout<<"No"<<endl;
if(flag==0) cout<<"No"<<endl;
}
return 0;
}