UVA 11624 Fire!

题目链接:UVA 11624 Fire!

题目大意:
一个平面迷宫中有一个人,迷宫中有些点起火了,火和人每个单位时间只能向相邻的格子移动,其中有一些空间被墙壁占据,问这个人在不被烧到的情况下,离开迷宫的最快时间。

题解:
首先用BFS预处理大火覆盖每一个能达到的地方的时间,之后再对人用BFS,只要人在大火之前到达一个地方,即为安全。
注意初始的火不一定只有一处。

#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
#define ms(a, b) memset(a, b, sizeof(a))
#define io_speed_up ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MAXN 1000 + 10
#define INF 0x3f3f3f3f

int t, n, m, step[MAXN][MAXN], sx, sy;
bool vis[MAXN][MAXN];
char a[MAXN][MAXN];
struct node {
	int x, y, t;
};
queue <node> q;
const int dx[] = {0, 0, 1, -1};
const int dy[] = {1, -1, 0, 0};

void fireBfs() {
	while (!q.empty()) {
		node u = q.front();
		q.pop();
		for (int i = 0; i < 4; ++i) {
			int xi = u.x + dx[i], yi = u.y + dy[i];
			if ((xi >= 1 && xi <= n && yi >= 1 && yi <= m) && a[xi][yi] != '#' && step[xi][yi] == INF) {
				q.push(node{xi, yi, 0});
				step[xi][yi] = step[u.x][u.y] + 1;
			}
		}
	}
}

void JoeBfs() {
	q.push(node{sx, sy, 0});
	vis[sx][sy] = true;
	while (!q.empty()) {
		node u = q.front();
		q.pop();
		if (u.x == n || u.x == 1 || u.y == 1 || u.y == m) {
			cout << u.t + 1 << endl;
			return;
		}
		for (int i = 0; i < 4; ++i) {
			int xi = u.x + dx[i], yi = u.y + dy[i];
			if ((xi >= 1 && xi <= n && yi >= 1 && yi <= m) && a[xi][yi] != '#' && !vis[xi][yi] && (u.t + 1 < step[xi][yi])) {
				q.push(node{xi, yi, u.t + 1});
				vis[xi][yi] = true;
			}
		}
	}
	cout << "IMPOSSIBLE" << endl;
}

int main() {
	io_speed_up;
	cin >> t;
	while (t--) {
		while (!q.empty()) q.pop();
		ms(vis, false);
		ms(step, INF);
		cin >> n >> m;
		for (int i = 1; i <= n; ++i) cin >> a[i] + 1;
		for (int i = 1; i <= n; ++i) {
			for (int j = 1; j <= m; ++j) {
				if (a[i][j] == 'J') {
					sx = i;
					sy = j;
				}
				if (a[i][j] == 'F') {
					q.push(node{i, j, 0});
					step[i][j] = 0;
				}
			}
		}
		fireBfs();
		while (!q.empty()) q.pop();
		JoeBfs();
	}
	return 0;
}
posted @ 2020-10-04 21:26  ZZHHOOUU  阅读(228)  评论(0编辑  收藏  举报