/*
思路:我想的是用深搜来解决这道题,首先他给了高度,圆的个数,和圆的半径。
我先设置了一个head和一个end,用于作为深搜的起点和终点;
我先挨个调取v数组中每个圆i的信息,先将他们的z轴高度与head(底边)和end(顶面)进行比较,
如果有相交,则将圆i push 进l[N]这个图中 head——>圆i 或 圆i——>end;
然后我判断两个圆( i 和 j )是否相交,如果相交,则视为 圆i 与圆j中 有一条无向边;
于是我们就得到了一个以圆的编号,head,end 为点,的图;
然后进行dfs 判断能否从head到达end;
*/
#include<bits/stdc++.h>
using namespace std;
const int N=1e4;
struct node_t
{
int x,y,z;
};
vector<int> l[N];
bool vis[N];
int flag=0;
bool dist(int x1,int x2,int y1,int y2,int z1,int z2,int r)
{
long long dis=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2);
long long R=4*r*r;
//cout<<"dis="<<dis<<" R="<<R<<endl;
if(dis<=R) return true;
else return false;
}
void dfs(int x,int end)
{
//cout<<"x="<<x<<" end="<<end<<endl;
if(x==end)
{
flag++;
return;
}
vis[x]=1;
for(int i=0;i<l[x].size();i++)
{
int u=l[x][i];
if(vis[u]==0) dfs(u,end);
}
}
int main()
{
ios::sync_with_stdio(false);
int T; cin>>T;
while(T--)
{
//cout<<"there"<<endl;
flag=0;
int n,h,r; cin>>n>>h>>r;
vector<node_t> v;
for(int i=1;i<=n;i++)
{
int x,y,z; cin>>x>>y>>z;
v.push_back({x,y,z});
}
int head=0,end=n+1;
/*for(int i=0;i<v.size();i++)
{
cout<<"圆"<<i+1<<"=("<<v[i].x<<","<<v[i].y<<","<<v[i].z<<")"<<endl;
}*/
for(int i=0;i<v.size();i++)
{
int x1=v[i].x,y1=v[i].y,z1=v[i].z;
if(z1-r<=0)
{
l[head].push_back(i+1);
//cout<<head<<"<->"<<i+1<<endl;
}
if(z1+r>=h)
{
l[i+1].push_back(end);
//cout<<i+1<<"<->"<<end<<endl;
}
for(int j=0;j<i;j++)
{
int x2=v[j].x,y2=v[j].y,z2=v[j].z;
if(dist(x1,x2,y1,y2,z1,z2,r))
{
l[i+1].push_back(j+1);
//cout<<i+1<<"<->"<<j+1<<endl;
l[j+1].push_back(i+1);
//cout<<j+1<<"<->"<<i+1<<endl;
}
}
}
for(int i=0;i<=n+1;i++) vis[i]=0;
dfs(head,end);
if(flag!=0) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
for(int i=0;i<=n+1;i++) l[i].resize(0);
}
return 0;
}
/*
1
2 5 1
0 0 1
0 0 4
*/
求大佬帮助