两次BFS,一次记录火在不同的时间蔓延的地方。第二次搜索最短路线。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
struct Node{
int x,y;
};
char map[1005][1005];
int fireMap[1005][1005],r[1005][1005];
Node JNode;
int R,C;
int dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
queue<Node> QF;
void fbfs(){
while (!QF.empty()) QF.pop();
Node fNode,FirstNode,NextNode;
for(int i=0;i<R;i++)
for(int j=0;j<C;j++)
if(map[i][j]=='F'){
fNode.x=i;fNode.y=j;
QF.push(fNode);
fireMap[fNode.x][fNode.y]=1;
}
while (!QF.empty()) {
FirstNode = QF.front();
QF.pop();
for(int i=0;i<4;i++){
NextNode.x=FirstNode.x+dir[i][0];
NextNode.y=FirstNode.y+dir[i][1];
if(NextNode.x < 0 || NextNode.x >= R || NextNode.y < 0 || NextNode.y >= C)
continue;
if(map[NextNode.x][NextNode.y]=='#')
continue;
if(fireMap[NextNode.x][NextNode.y]==0){
fireMap[NextNode.x][NextNode.y]=fireMap[FirstNode.x][FirstNode.y]+1;
QF.push(NextNode);
}
}
}
QF.push(JNode);
r[JNode.x][JNode.y]=1;
while (!QF.empty()) {
FirstNode = QF.front();
QF.pop();
if(FirstNode.x==0 || FirstNode.x==R-1 || FirstNode.y==0 || FirstNode.y==C-1){
printf("%d\n",r[FirstNode.x][FirstNode.y]);
return;
}
for(int i=0;i<4;i++){
Node Next;
Next.x = FirstNode.x+dir[i][0];
Next.y = FirstNode.y+dir[i][1];
if(Next.x<0 || Next.x>=R || Next.y<0 || Next.y>=C) continue;
if(map[Next.x][Next.y]=='#') continue;
if(r[Next.x][Next.y]==0 && (r[FirstNode.x][FirstNode.y]+1 < fireMap[Next.x][Next.y] || fireMap[Next.x][Next.y]==0)){
r[Next.x][Next.y]=r[FirstNode.x][FirstNode.y]+1;
QF.push(Next);
}
}
}
puts("IMPOSSIBLE");
}
int main(){
// freopen("cin", "r", stdin);
// freopen("cout", "w", stdout);
int c;
scanf("%d",&c);
while(c--){
memset(r,0,sizeof(r));
memset(fireMap,0,sizeof(fireMap));
scanf("%d%d",&R,&C);
for(int i=0;i<R;i++){
scanf("%s",map[i]);
for(int j=0;j<C;j++){
if(map[i][j]=='J') {JNode.x=i;JNode.y=j;}
}
}
fbfs();
}
return 0;
}