题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2671
题目大意:迷宫里有几个地方失火了,小J要赶快出去,出口就是迷宫的没有障碍物的边界地方,但是火势蔓延速度和小J的速度都是一秒一个并且只能走到相邻的格子。问小明能不能走出去,若能,最少多长时间?
解题思路:两次宽搜即可。先搜索火再搜索人,看人走到边界的时候用的时间是否比火少。由于火不止一处,因此将初始为火的地方全部push到队列中然后就和普通的搜索一样了。
代码:
const int maxn = 1010; char maze[maxn][maxn]; int n, m; struct cell{ int i, j, t; cell(int x, int y): i(x), j(y), t(0) {} cell(int x, int y, int ti): i(x), j(y), t(ti) {} }; vector<cell> fires; int jarrti[maxn][maxn], farrti[maxn][maxn]; short vis[maxn][maxn]; queue<cell> q; int bfsj(int ti, int tj){ memset(vis, 0, sizeof(vis)); memset(jarrti, 0x3f, sizeof(jarrti)); while(!q.empty()) q.pop(); vis[ti][tj] = 1; jarrti[ti][tj] = 0; cell u(ti, tj, 0); q.push(u); int ans = inf; while(!q.empty()){ u = q.front(); q.pop(); if((u.i == n - 1 || u.j == m - 1 || u.i == 0 || u.j == 0) && u.t < farrti[u.i][u.j]) return u.t + 1; u.t++; for(int i = 0; i < 4; i++){ cell v = u; v.i += iadd[i]; v.j += jadd[i]; if(v.i >= n || v.j >= m || v.i < 0 || v.j < 0) continue; if(maze[v.i][v.j] == '#' || maze[v.i][v.j] == 'F') continue; if(!vis[v.i][v.j]){ vis[v.i][v.j] = 1; jarrti[v.i][v.j] = v.t; q.push(v); } } } return ans < inf? ans: -1; } void bfsf(){ memset(vis, 0, sizeof(vis)); memset(farrti, 0x3f, sizeof(farrti)); while(!q.empty()) q.pop(); for(int i = 0; i < fires.size(); i++){ int fi = fires[i].i, fj = fires[i].j; vis[fi][fj] = 1; q.push(cell(fi, fj, 0)); farrti[fi][fj] = 0; } while(!q.empty()){ cell u = q.front(); q.pop(); u.t++; for(int i = 0; i < 4; i++){ cell v = u; v.i += iadd[i]; v.j += jadd[i]; if(v.i >= n || v.j >= m || v.i < 0 || v.j < 0) continue; if(maze[v.i][v.j] == '#') continue; if(!vis[v.i][v.j]){ vis[v.i][v.j] = 1; farrti[v.i][v.j] = v.t; q.push(v); } } } } int main(){ int T; scanf("%d", &T); while(T--){ fires.clear(); while(!q.empty()) q.pop(); scanf("%d %d", &n, &m); int ji, jj; for(int i = 0; i < n; i++){ for(int j = 0; j < m; j++){ scanf(" %c", &maze[i][j]); if(maze[i][j] == 'F') fires.push_back(cell(i, j)); if(maze[i][j] == 'J') ji = i, jj = j; } } bfsf(); int ans = bfsj(ji, jj); if(ans == -1) puts("IMPOSSIBLE"); else printf("%d ", ans); } }