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 ",ans); else puts("IMPOSSIBLE"); } return 0; }