多源bfs。注意J一开始就在边界的特殊情况。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#define ll long long
#define INF 200000000
#define MOD 1000007
#define MAXN 4000*1005
using namespace std;
char grid[1005][1005];
int dist[1005][1005];
int M[4][2]= {{1,0},{-1,0},{0,1},{0,-1}};
struct Point
{
int x,y,time;
Point(int a=0,int b=0,int c=0):x(a),y(b),time(c) {}
};
Point st;
int R,C;
bool Range(int x,int y)
{
if(x<1||y<1||x>R||y>C) return false;
return true;
}
bool Safe(int x,int y)
{
if(x==1||x==R||y==1||y==C) return true;
return false;
}
void bfs_fire(int x,int y)
{
queue<Point> que;
que.push(Point(x,y,0));
dist[x][y]=0;
while(!que.empty())
{
Point p=que.front();
que.pop();
for(int i=0; i<4; ++i)
{
int nx=p.x+M[i][0],ny=p.y+M[i][1],t=p.time+1;
if(!Range(nx,ny)||grid[nx][ny]=='#') continue;
if(dist[nx][ny]<=t) continue;
dist[nx][ny]=t;
que.push(Point(nx,ny,t));
}
}
}
bool vis[1005][1005];
int bfs_J(int x,int y)
{
if(Safe(x,y)) return 0;
queue<Point> que;
que.push(Point(x,y,0));
memset(vis,0,sizeof(vis));
vis[x][y]=true;
while(!que.empty())
{
Point p=que.front();
que.pop();
for(int i=0; i<4; ++i)
{
int nx=p.x+M[i][0],ny=p.y+M[i][1],t=p.time+1;
if(vis[nx][ny]||!Range(nx,ny)||grid[nx][ny]=='#'||t>=dist[nx][ny]) continue;
vis[nx][ny]=true;
if(Safe(nx,ny)) return t;
que.push(Point(nx,ny,t));
}
}
return -1;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&R,&C);
for(int i=1; i<=R; ++i)
scanf("%s",grid[i]+1);
memset(dist,0x7f,sizeof(dist));
for(int i=1; i<=R; ++i)
for(int j=1; j<=C; ++j)
{
if(grid[i][j]=='F') bfs_fire(i,j);
else if(grid[i][j]=='J')
{
st.x=i;
st.y=j;
}
}
int ans=bfs_J(st.x,st.y);
if(ans==-1) puts("IMPOSSIBLE");
else printf("%d\n",ans+1);
}
return 0;
}