预处理一下每个点的着火事件。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=1000+5;
char map[maxn][maxn];
int fire[maxn][maxn],vis[maxn][maxn];
int r,c;
int sx,sy;
int dx[4]={-1,0,1,0};
int dy[4]={0,-1,0,1};
struct node{
int x,y,t;
};
#define ss(x) scanf("%d",&x)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
bool inside(int x,int y) {return x>=1&&x<=r&&y>=1&&y<=c;}
void build_fire_time()
{
memset(fire,0x7f,sizeof(fire));
memset(vis,0,sizeof(vis));
queue<node> q;
rep(i,1,r) rep(j,1,c) if(map[i][j]=='F') {q.push((node){i,j,1});fire[i][j]=1;vis[i][j]=1;}
while(!q.empty())
{
node last=q.front();q.pop();
rep(i,0,3){
node now;
now.x=last.x+dx[i];
now.y=last.y+dy[i];
now.t=last.t+1;
if(inside(now.x,now.y)&&map[now.x][now.y]!='#'&&!vis[now.x][now.y]) {
vis[now.x][now.y]=1;
fire[now.x][now.y]=min(fire[now.x][now.y],now.t);q.push(now);
}
}
}
}
void findsorce(){
rep(i,1,r) rep(j,1,c) if(map[i][j]=='J') {sx=i;sy=j;return ;}
}
void findpath(){
memset(vis,0,sizeof(vis));
queue<node> q;
q.push((node){sx,sy,1});
vis[sx][sy]=1;
while(!q.empty())
{
node last=q.front();q.pop();
if(last.x==1||last.x==r||last.y==1||last.y==c) {printf("%d\n",last.t);return ;}
rep(i,0,3){
int x,y,t;
x=last.x+dx[i];
y=last.y+dy[i];
t=last.t+1;
if(inside(x,y)&&map[x][y]!='#'&&!vis[x][y]&&t<fire[x][y]) {vis[x][y]=1;q.push((node){x,y,t});}
}
}
printf("IMPOSSIBLE\n");
}
int main()
{
int t;ss(t);
while(t--)
{
ss(r);ss(c);
rep(i,1,r) scanf("%s",map[i]+1);
build_fire_time();
findsorce();
findpath();
}
return 0;
}