通过这道题,对双向bfs的理解又深入了,写篇博客纪念。
常规双向bfs是这个格式:
while(! q1. empty() || ! q2. empty()){
if(! q1. empty()){
}
if(! q2. empty()){
}
}
但是这么写的基础是x和y的速度一样,但这题不一样!所以要使用下面的写法(ps:以后的双向bfs我还是都使用下面的写法吧)
while(! q1. empty() || ! q2. empty()){
int len1 = q1. size(), len2 = q2. size();
while(len1 --){
}
while(len2 --){
}
}
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000;
int dir[4][2] = {{0,1}, {0,-1}, {-1,0}, {1,0}};
struct node{
int x, y;
node(){}
node(int x,int y):x(x),y(y){}
};
int n, m;
char maze[maxn][maxn];
bool visit0[maxn][maxn];
bool visit1[maxn][maxn];
node ghost[2], st0, st1;
bool check(int x, int y){
if(x >= 0 && x < n && y >= 0 && y < m) return true;
else return false;
}
bool validZ(int x,int y, int cost){
if(2 * cost < min(abs(x - ghost[0]. x) + abs(y-ghost[0].y), abs(x-ghost[1].x)+abs(y-ghost[1].y)))
return true;
return false;
}
int two_bfs(){
int k, t = 0, siz;
node now;
queue<node>Q0;
queue<node>Q1;
while(!Q0.empty()) Q0.pop();
while(!Q1.empty()) Q1.pop();
memset(visit0,false,sizeof(visit0));
memset(visit1,false,sizeof(visit1));
visit0[st0.x][st0.y]=true,visit1[st1.x][st1.y]=true;
Q0.push(st0);
Q1.push(st1);
while(!Q0.empty()||!Q1.empty()){
++t;
k=3;
while((k--)){
siz=Q0.size();
while(siz--){
now=Q0.front();
Q0.pop();
if(validZ(now.x,now.y,t)==false) continue;
for(int i=0;i<4;i++){
int dx=now.x+dir[i][0];
int dy=now.y+dir[i][1];
if(check(dx,dy)&&validZ(dx,dy,t)&&!visit0[dx][dy]&&maze[dx][dy]!='X'){
if(visit1[dx][dy]==true) return t;
visit0[dx][dy]=true;
Q0.push(node(dx,dy));
}
}
}
}
siz=Q1.size();
while(siz--){
now=Q1.front();
Q1.pop();
if(validZ(now.x,now.y,t)==false) continue;
for(int i=0;i<4;i++){
int dx=now.x+dir[i][0];
int dy=now.y+dir[i][1];
if(check(dx,dy)&&validZ(dx,dy,t)&&!visit1[dx][dy]&&maze[dx][dy]!='X'){
if(visit0[dx][dy]==true) return t;
visit1[dx][dy]=true;
Q1.push(node(dx,dy));
}
}
}
}
return -1;
}
int main(){
int tt,k;
scanf("%d",&tt);
while(tt--){
k=0;
scanf("%d%d",&n,&m);
for(int i=0; i<n; i++) scanf("%s",maze[i]);
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
if(maze[i][j]=='Z'){
ghost[k++]=node(i,j);
}else if(maze[i][j]=='M'){
st0=node(i,j);
}else if(maze[i][j]=='G'){
st1=node(i,j);
}
}
}
int ans=two_bfs();
printf("%d\n",ans);
}
return 0;
}