题目:题目
大意:在迷宫中,人J逃出去,,,出区域就算,迷宫中还有火,火会像四周蔓延,人不能走火易经到达的位置,求最短多长时间能出来
解体思路:用两次bfs,第一次记录火到每个地点的时间,第二次求人道每个地方的时间,但是要求,人到的哪个位置的时间i火要早
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<iostream>
using namespace std;
int n,m;
const int maxn = 1000+10;
string mp[maxn];
struct Node{
int x;int y;int t;
Node(){};
Node(int xx,int yy,int tt):x(xx),y(yy),t(tt){};
}start;
bool vis[maxn][maxn];
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int ts[maxn][maxn];
queue<Node> q;
const int inf = 0x3f3f3f3f;
bool ok(int x,int y){
if(x >= 0 && x < n && y >= 0 && y < m) return true;
return false;
}
void init(){
bool isfire = false;
while(!q.empty()) q.pop();
memset(ts,inf,sizeof(ts)); 这里把火的位置初始化最大值,开始都是0WA了,
memset(vis,false,sizeof(vis));
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(mp[i][j]=='J'){ //记录人的坐标
start.x=i;
start.y=j;
start.t=0;
}
if(mp[i][j]=='F'){ //记录火的其实坐标放进队列中
isfire=true;
vis[i][j]=true;
ts[i][j]=0;
q.push(Node(i,j,0));
}
}
}
if(!isfire)
return ;
while(!q.empty()){ //求火的位置并进行记录
Node temp = q.front();
q.pop();
for(int i=0;i<4;i++){
int dx=temp.x+dir[i][0];
int dy=temp.y+dir[i][1];
if(ok(dx,dy) && !vis[dx][dy] && mp[dx][dy]=='.'){
vis[dx][dy]=true;
ts[dx][dy]=temp.t+1;
q.push(Node(dx,dy,temp.t+1));
}
}
}
}
int bfs(){
while(!q.empty()) q.pop();
q.push(start);
memset(vis,false,sizeof(vis));
vis[start.x][start.y]=true;
while(!q.empty()) //求人的位置
{
Node temp = q.front();
q.pop();
for(int i=0;i<4;i++){
int dx=temp.x+dir[i][0];
int dy=temp.y+dir[i][1];
if(!ok(dx,dy)) return temp.t+1;
if(!vis[dx][dy] && mp[dx][dy]=='.' && temp.t+1<ts[dx][dy])
{
q.push(Node(dx,dy,temp.t+1));
vis[dx][dy]=true;
}
}
}
return inf;
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
cin>>mp[i];
}
init();
int ans=bfs();
if(ans!=inf){
printf("%d\n",ans);
}
else{
printf("IMPOSSIBLE\n");
}
}
return 0;
}