題目連接:https://cn.vjudge.net/problem/UVA-11624c++
題意:數組
給出一個 $n \times m$ 的矩陣,上面有的格子能走,有的格子是牆不能走。spa
有若干個點是火源,火每分鐘都往上下左右蔓延一格(不能越牆)。又給出一個點是Joe的出發點,他只要能在不碰到火的前提下走出該矩陣,就算逃生成功,要求最小的逃生時間。.net
題解:code
顯然能夠把火和人一塊兒扔進隊列裏BFS,只要初始狀態的時候火比人先進隊,那麼日後在BFS的每一層內永遠都是火比人先進隊。blog
而後,vis數組正好也能夠用來被火給標記掉,可使得當前時間下人不能走火走過格子。隊列
AC代碼:ci
#include<bits/stdc++.h> using namespace std; const int maxn=1003; const int INF=0x3f3f3f3f; const int dx[4]={1,0,-1,0}; const int dy[4]={0,1,0,-1}; int n,m; char tmp[maxn]; int mp[maxn][maxn]; struct Node{ bool fire; int x,y; int step; Node(){} Node(bool _fire,int _x,int _y,int _step) { fire=_fire; x=_x, y=_y; step=_step; } }joe,fire[maxn*maxn]; int firecnt; int vis[maxn][maxn]; queue<Node> Q; inline bool border(Node o) { return o.x==1 || o.x==n || o.y==1 || o.y==m; } int bfs() { memset(vis,0,sizeof(vis)); while(!Q.empty()) Q.pop(); for(int i=1;i<=firecnt;i++) { fire[i].fire=1; fire[i].step=0; Q.push(fire[i]); vis[fire[i].x][fire[i].y]=1; } joe.step=joe.fire=0; Q.push(joe); vis[joe.x][joe.y]=1; while(!Q.empty()) { Node now=Q.front(); Q.pop(); if(!now.fire && border(now)) return now.step; for(int k=0;k<4;k++) { Node nxt=Node(now.fire,now.x+dx[k],now.y+dy[k],now.step+1); if(mp[nxt.x][nxt.y]) continue; if(vis[nxt.x][nxt.y]) continue; vis[nxt.x][nxt.y]=1; Q.push(nxt); } } return -1; } int main() { int T; cin>>T; while(T--) { scanf("%d%d",&n,&m); memset(mp,1,sizeof(mp)); firecnt=0; for(int i=1;i<=n;i++) { scanf("%s",tmp+1); for(int j=1;j<=m;j++) { if(tmp[j]=='#') mp[i][j]=1; if(tmp[j]=='.') mp[i][j]=0; if(tmp[j]=='J') joe.x=i, joe.y=j, mp[i][j]=0; if(tmp[j]=='F') firecnt++, fire[firecnt].x=i, fire[firecnt].y=j, mp[i][j]=0; } } int ans=bfs(); if(ans==-1) printf("IMPOSSIBLE\n"); else printf("%d\n",ans+1); } }