预处理出所有可以相连的圆心(他们的圆可以相交或相接),并设置起点和终点,以及起点和终点可以相连的圆心,将所有相连的路径存储在二维数组中,数组下标代表相连两点圆心编号,接着从起点到终点进行深度搜索即可

#include<bits/stdc++.h>
using namespace std;
int n,h,r;
const int M=1e3+5;
struct node{
    long long x,y,z;
}a[M];
int mp[M][M];
int vis[M];
bool xianglian(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 dfs(int x,int e){
    vis[x]=1;
    //到达终点,返回true
    if(x==e)    return 1;
    for(int i=1;i<=n+1;i++){
        if(!vis[i]&&mp[x][i])
            if(dfs(i,e))  return 1;
    }
    return 0;
}

int main(){
    int t;
    cin>>t;
    while(t--){
        memset(mp,0,sizeof(mp));
        memset(vis,0,sizeof(vis));
        memset(a,0,sizeof(a));
        cin>>n>>h>>r;
        for(int i=1;i<=n;i++){
            cin>>a[i].x>>a[i].y>>a[i].z;
            if(a[i].z<=r)    mp[0][i]=1;    
            if(h-a[i].z<=r)    mp[i][n+1]=1;  
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(i!=j&&xianglian(i,j))
                    mp[i][j]=1;
            }
        }
        if(dfs(0,n+1)) cout<<"Yes\n";
        else    cout<<"No\n";
    }
    return 0;
}