题目链接:​​https://cn.vjudge.net/problem/UVA-11624​

 

题意:

给出一个 $n \times m$ 的矩阵,上面有的格子能走,有的格子是墙不能走。

有若干个点是火源,火每分钟都往上下左右蔓延一格(不能越墙)。又给出一个点是Joe的出发点,他只要能在不碰到火的前提下走出该矩阵,就算逃生成功,要求最小的逃生时间。

 

题解:

显然可以把火和人一起扔进队列里BFS,只要初始状态的时候火比人先进队,那么往后在BFS的每一层内永远都是火比人先进队。

然后,vis数组正好也可以用来被火给标记掉,可以使得当前时间下人不能走火走过格子。

 

AC代码:



#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);
}
}