首先我们从题目中得知,每头牛的对讲机的有效传输半径为一个圆心为 ( x [ i ] , y [ i ] ) \left(x[i],y[i]\right) (x[i],y[i]) 半径为 p [ i ] p[i] p[i] 的圆。
这样我们就可以进行 B F S BFS BFS 去查找当前位置上的牛所能传出到的所有牛了。
当然,也可以理解为这是一个 变种 的连通块,每次可以跳到一个与当前点的 欧几里得距离 $ \leq p[i]$ 的位置。
执行 n n n 次,每次更新最大值即可。
注意:每次操作前要清空队列和vis数组,还要将 s u m sum sum 初始化为 1 1 1 。
#include<bits/stdc++.h>
using namespace std;
#define int long long
struct node{
int h,l,zhi;
};
queue<node>q;
int n,sum,ans;
int x[205],y[205],p[205];
bool vis[205];
//因为存坐标的二维数组开不下,所以这里的vis是来存位置的(第几个)
void bfs(int x1,int y1,int p1,int t1){
while(!q.empty())
q.pop();
node t;
t.l=x1;
t.h=y1;
t.zhi=p1;
q.push(t);
vis[t1]=true;
while(!q.empty()){
node now=q.front();
q.pop();
for(int i=1;i<=n;i++)
if(vis[i]==false){
double pd=sqrt((x[i]-now.l)*(x[i]-now.l)+(y[i]-now.h)*(y[i]-now.h));
if(pd<=now.zhi){
sum++;
node tmp;
tmp.l=x[i];
tmp.h=y[i];
tmp.zhi=p[i];
vis[i]=true;
q.push(tmp);
}
}
}
}
//简单的BFS操作
signed main(){
scanf("%lld",&n);
for(int i=1;i<=n;i++)
scanf("%lld%lld%lld",&x[i],&y[i],&p[i]);
for(int i=1;i<=n;i++){
sum=1;
memset(vis,false,sizeof(vis));
bfs(x[i],y[i],p[i],i);
ans=max(ans,sum); //每次更新ans
}
printf("%lld",ans);
return 0;
}