题目:一个平面迷宫中有一个人,迷宫中有些点起火了,火和人每个单位时间只能向相邻的格子移动,
其中有一些空间被墙壁占据,问这个人在不背或烧到的情况下,离开迷宫的最快时间。
思路是先用bfs预处理每个格子起火的时间,在来一次bfs走迷宫,入队时判断着火事件和父节点时间大小关系
代码如下:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
using namespace std;
#define LL long long
const int maxr = 1000 + 5;
const int maxc = 1000 + 5;
const int dirx[] = {-1, 0, 1, 0};
const int diry[] = {0, -1, 0, 1};
const int INF = 100000000;
struct node {
int x; int y;
};
int G[maxr][maxc], fire_time[maxr][maxc], timeuse[maxr][maxc];
//0表示障碍,1表示空地,2表示着火
void bfs(int r, int c) {
queue<node> fire;
for(int i = 1; i <= r; i++)
for(int j = 1; j <= c; j++) {
fire_time[i][j] = INF;
if(G[i][j] == 2) {
fire_time[i][j] = 0;
fire.push((node){i, j});
}
}
while(!fire.empty()) {
node f = fire.front(); fire.pop();
for(int i = 0; i < 4; i++) {
int nx = f.x + dirx[i], ny = f.y + diry[i];
if(nx > 0 && nx <= r && ny > 0 && ny <= c && G[nx][ny] == 1 && fire_time[nx][ny] == INF) {
fire_time[nx][ny] = fire_time[f.x][f.y] + 1;
fire.push((node){nx, ny});
}
}
}
}
void bfs_mg(int jx, int jy, int r, int c) {
for(int i = 1; i <= r; i++)
for(int j = 1; j <= c; j++) timeuse[i][j] = INF;
queue<node> mg;
timeuse[jx][jy] = 0;
mg.push((node){jx, jy});
while(!mg.empty()) {
node u = mg.front(); mg.pop();
for(int i = 0; i < 4; i++){
int nx = u.x + dirx[i];
int ny = u.y + diry[i];
if(nx > 0 && nx <= r && ny > 0 && ny <= c && G[nx][ny] == 1 && timeuse[nx][ny] == INF && timeuse[u.x][u.y] < fire_time[nx][ny] - 1){
timeuse[nx][ny] = timeuse[u.x][u.y] + 1;
mg.push((node){nx, ny});
}
}
}
}
void solve(int r, int c){
int ans = INF;
for(int i = 1; i <= r; i++)
ans = min(ans, timeuse[i][1]);
for(int i = 1; i <= r; i++)
ans = min(ans, timeuse[i][c]);
for(int j = 1; j <= c; j++)
ans = min(ans, timeuse[1][j]);
for(int j = 1; j <= c; j++)
ans = min(ans, timeuse[r][j]);
if(ans == INF) printf("IMPOSSIBLE\n");
else printf("%d\n", ans + 1);
}
int main() {
//freopen("input.txt", "r", stdin);
int t; scanf("%d", &t);
while(t--) {
int r, c; scanf("%d%d", &r, &c);
int jx, jy;
for(int i = 1; i <= r; i++) {
getchar();
for(int j = 1; j <= c; j++) {
char x; scanf("%c", &x);
if(x == '#') G[i][j] = 0;
else if(x == '.') G[i][j] = 1;
else if(x == 'F') G[i][j] = 2;
else {G[i][j] = 0; jx = i; jy = j;}
}
}
bfs(r, c);
bfs_mg(jx, jy, r, c);
solve(r, c);
//for(int i = 1; i <= r; i++)
// for(int j = 1; j <= c; j++) printf("%d ", fire_time[i][j]);
//for(int i = 1; i <= r; i++)
// for(int j = 1; j <= c; j++) printf("%d ", time[i][j]);
//for(int i = 1; i <= r; i++)
// for(int j = 1; j <= c; j++) printf("%d ", G[i][j]);
}
return 0;
}