UVA - 11624 Fire!
题目
给一个迷宫,起始位置,还有着火点,每过一个时间,着火点都会蔓延,问最终能否从迷宫逃出。
分析
如果没有着火的情况,直接BFS模板题,加上着火的话,可以预处理每个点被蔓延的时间,到时候 b f s bfs bfs 能不能走出去的时候,不能走当前已经着火的地方。
预处理着火的地方,要将所有起始找着火点都加入初始队列,相当于多个源点。
代码
#include <cstdio>
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 1e3 + 10;
int t, n, m, k, ans;
char a[N][N];
int ti[N][N], vis[N][N], tx[N], ty[N];
int dir[][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
struct node{
int x, y, step;
node(int x, int y, int step) : x(x), y(y), step(step) {}
};
int f(int x, int y){
if(x >= 1 && x <= n && y >= 1 && y <= m)
return true;
return false;
}
void bfs(){
queue<node> q;
memset(vis, 0, sizeof(vis));
for(int i = 0; i < k; i++){ // 多源点一起插入
q.push(node(tx[i], ty[i], 1));
// cout << tx[i] << ty[i] << endl;
ti[tx[i]][ty[i]] = 0;
vis[tx[i]][ty[i]] = 1;
}
while(!q.empty()){
node cnt = q.front();
q.pop();
for(int i = 0; i < 4; i++){
int xx = cnt.x + dir[i][0];
int yy = cnt.y + dir[i][1];
if(f(xx, yy) && !vis[xx][yy] && a[xx][yy] != '#'){
vis[xx][yy] = 1;
ti[xx][yy] = cnt.step;
q.push(node(xx, yy, cnt.step+1));
}
}
}
}
int cal(int x, int y){
queue<node> q;
memset(vis, 0, sizeof(vis));
q.push(node(x, y, 0));
while(!q.empty()){
node cnt = q.front();
q.pop();
if(cnt.x == 1 || cnt.x == n || cnt.y == 1 || cnt.y == m){
ans = cnt.step + 1;
return 1;
}
for(int i = 0; i < 4; i++){
int xx = cnt.x + dir[i][0];
int yy = cnt.y + dir[i][1];
if(f(xx, yy) && !vis[xx][yy] && a[xx][yy] != '#' && cnt.step+1<ti[xx][yy]){
vis[xx][yy] = 1;
q.push(node(xx, yy, cnt.step+1));
}
}
}
return 0;
}
int main()
{
std::ios::sync_with_stdio(false);
// cin.tie(0);
// cout.tie(0);
cin >> t;
while(t--){
cin >> n >> m;
int x, y;
k = 0;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
cin >> a[i][j];
if(a[i][j] == 'J'){
x = i, y = j;
}else if(a[i][j] == 'F'){
tx[k] = i, ty[k++] = j;
}
}
}
memset(ti, INF, sizeof(ti));
bfs();
if(cal(x, y)){
cout << ans << endl;
}else{
cout << "IMPOSSIBLE" << endl;
}
}
}
/*
2
4 4
####
#JF#
#..#
#..#
3 3
###
#J.
#.F
*/