http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2671
首先对火进行一次bfs,得到着火时间,然后对人进行一次bfs,只允许进入还没有着火的点
注意:出迷宫条件是从任何一墙出去,过墙需要1时间
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int maxn=1003;
const int inf=0x3fffffff;
char maz[maxn][maxn];
int time[maxn][maxn];
int dp[maxn][maxn];
int n,m;
queue<int> que;
const int dx[8]={0,0,1,-1,1,1,-1,-1};
const int dy[8]={1,-1,0,0,1,-1,1,-1};
struct pnt {
int x,y;
pnt(){x=y=0;}
pnt(int tx,int ty){x=tx,y=ty;}
};
bool in(int x,int y){
return x>=0&&x<n&&y>=0&&y<m;
}
void bfs(){
while(!que.empty()){
int x=que.front()/maxn,y=que.front()%maxn;que.pop();
for(int i=0;i<4;i++){
int tx=x+dx[i],ty=y+dy[i];
if(in(tx,ty)&&maz[tx][ty]!='#'&&time[tx][ty]>time[x][y]+1){
time[tx][ty]=time[x][y]+1;
que.push(tx*maxn+ty);
}
}
}
}
int bfs2(int sx,int sy){
while(!que.empty())que.pop();
dp[sx][sy]=0;
que.push(sx*maxn+sy);
while(!que.empty()){
int x=que.front()/maxn,y=que.front()%maxn;que.pop();
for(int i=0;i<4;i++){
int tx=x+dx[i],ty=y+dy[i];
if(!in(tx,ty)){
return dp[x][y]+1;
}
if(maz[tx][ty]!='#'&&time[tx][ty]>dp[x][y]+1&&dp[tx][ty]>dp[x][y]+1){
dp[tx][ty]=dp[x][y]+1;
que.push(tx*maxn+ty);
}
}
}
return -1;
}
void init(){
while(!que.empty())que.pop();
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
time[i][j]=inf;
dp[i][j]=inf;
}
}
}
int main(){
int T;
scanf("%d",&T);
for(int ti=1;scanf("%d%d",&n,&m)==2&&ti<=T;ti++){
for(int i=0;i<n;i++){
scanf("%s",maz[i]);
}
init();
int sx,sy;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(maz[i][j]=='F'){
que.push(i*maxn+j);
time[i][j]=0;
}
else if(maz[i][j]=='J'){
sx=i;
sy=j;
}
}
}
bfs();
int ans=bfs2(sx,sy);
if(ans!=-1)printf("%d\n",ans);
else puts("IMPOSSIBLE");
}
return 0;
}