链接
知识点
DFS,BFS
思路
解法一
- DFS算法,不撞南墙不回头的算法,一条道走到底,相当于树的深度遍历对于当前状态
- 我要把我能感染的给感染,然后跳转到下一个被感染的对象,以此类推直到不能感染为止,此时处于回溯状态,然后再在上一个状态下去感染其他状态,周而复始
- 如果下一个状态已经被感染了,那么跳过即可。
DFS代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3 + 5;
int n,D;
struct people {
int x, y;
bool flag = false;
}People[N];
int getDistince(int x1, int y1, int x2, int y2){
int a = pow(x1-x2,2);
int b = pow(y1-y2,2);
return a + b;
}
bool pd(int x1, int y1, int x2, int y2){
if(D*D > getDistince(x1, y1, x2, y2))
return true;
return false;
}
void DFS(int x, int y){
for (int i = 1; i <= n; i++){
if(People[i].flag)continue;
if (pd(x, y, People[i].x, People[i].y)){
People[i].flag = true;
DFS(People[i].x, People[i].y);
}
}
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++){
cin >> People[i].x >> People[i].y;
}
cin >> D;
People[1].flag = true;
DFS(People[1].x, People[1].y);
for (int i = 1; i <= n; i++)
cout<<People[i].flag<<endl;
return 0;
}
解法二
- 使用BFS搜索算法,从当前状态扩展到其他状态,用一个队列维护当前状态,通过标记是否被诅咒使得每一个节点只遍历一次
- 根据当前状态与其他状态之间的距离是否合法来判断是否入队(被标记)
- 当队列为空时,所有可以被标记的都已经被标记完成,此过程相当于对树的层序遍历
BFS代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3+10;
int n,D;
struct node{
int x;
int y;
bool flag;
}people[N];
queue<node>q;
int getDistince(int x1, int y1, int x2, int y2){
int a = pow(x1-x2,2);
int b = pow(y1-y2,2);
return a + b;
}
bool pd(int x1, int y1, int x2, int y2){
if(D*D > getDistince(x1, y1, x2, y2))
return true;
return false;
}
void BFS(int x,int y){
q.push(people[1]);
while(!q.empty()){
node now = q.front();
q.pop();
for(int i = 1;i<=n;i++){
if(people[i].flag) continue;
if(pd(x,y,people[i].x,people[i].y)){
people[i].flag = true;
q.push(people[i]);
}
}
}
}
int main(){
cin>>n;
for(int i = 1;i<=n;i++){
cin>>people[i].x>>people[i].y;
}
cin>>D;
people[1].flag = true;
BFS(people[1].x,people[1].y);
for(int i = 1;i<=n;i++){
cout<<people[i].flag<<endl;
}
return 0;
}