首先预处理出每个位置被大火烧到的时间,这个也是用bfs计算火的路径。
然后再正常对Joe逃跑路径bfs。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 1005
#include <queue>
int R,C;
int F[maxn][maxn];
char M[maxn][maxn];
bool vis[maxn][maxn];
int dir[4][2]={{0,1},{0,-1},{-1,0},{1,0}};
struct node{
int x,y,t;
node(){}
node(int x,int y,int t):x(x),y(y),t(t){}
};
bool C1(int x,int y){
if(x>=0&&x<R&&y>=0&&y<C&&!vis[x][y]) return 1;
return 0;
}
bool C2(int x,int y,int t){
if(x<0||x>=R||y<0||y>=C||vis[x][y]) return 0;
else if(F[x][y]!=-1&&F[x][y]<=t) return 0;
return 1;
}
bool OK(int x,int y){
if(x==0||y==0||x==R-1||y==C-1)
return 1;
return 0;
}
void init(){
memset(vis,0,sizeof(vis));
memset(F,-1,sizeof(F));
queue<node> Q;
for(int i=0;i<R;i++){
for(int j=0;j<C;j++){
if(M[i][j]=='F'){
Q.push(node(i,j,0));
vis[i][j]=1;
F[i][j]=0;
}
if(M[i][j]=='#') vis[i][j]=1;
}
}
while(!Q.empty()){
node cur=Q.front();
Q.pop();
for(int i=0;i<4;i++){
int tx=cur.x+dir[i][0];
int ty=cur.y+dir[i][1];
if(C1(tx,ty)){
Q.push(node(tx,ty,cur.t+1));
F[tx][ty]=cur.t+1;
vis[tx][ty]=1;
}
}
}
memset(vis,0,sizeof(vis));
for(int i=0;i<R;i++){
for(int j=0;j<C;j++){
if(M[i][j]=='#') vis[i][j]=1;
}
}
}
int bfs(int x,int y){
queue<node> Q;
Q.push(node(x,y,0));
if(OK(x,y)){
return 0;
}
vis[x][y]=1;
while(!Q.empty()){
node cur=Q.front();
Q.pop();
for(int i=0;i<4;i++){
int tx=cur.x+dir[i][0];
int ty=cur.y+dir[i][1];
if(C2(tx,ty,cur.t+1)){
if(OK(tx,ty)) return cur.t+1;
Q.push(node(tx,ty,cur.t+1));
vis[tx][ty]=1;
}
}
}
return -1;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&R,&C);
for(int i=0;i<R;i++){
scanf("%s",M[i]);
}
init();
int res=-1;
for(int i=0;i<R;i++){
for(int j=0;j<C;j++){
if(M[i][j]=='J'){
res=bfs(i,j);
break;
}
}
}
if(res==-1) printf("IMPOSSIBLE\n");
else printf("%d\n",res+1);
}
return 0;
}
/*
2
4 4
####
#JF#
#..#
#..#
3 3
###
#J.
#.F
*/
本文介绍了一种使用两次广度优先搜索(BFS)来解决火灾中人物(Joe)逃生路径的问题。首先通过BFS预处理出火焰蔓延的时间,然后再次使用BFS找出人物能够逃出建筑物的最短时间。
453

被折叠的 条评论
为什么被折叠?



