https://vjudge.ppsucxtt.cn/problem/UVA-11624node
迷宮裏一個或多個位置有火,火沒一秒蔓延到上下左右四個位置,Jor一秒只能上下左右移動一格,求Jor逃出在不趕上或逃出迷宮的最快時間。ios
Jor移動的方向用不少中變化,而火只會隨着時間向四個方向蔓延,因此能夠將Jor和火勢蔓延分紅兩個BFS,最關鍵一點就是Jor到達(i,j)點時(i,j)尚未火,因此能夠經過bfs_fire求出每一個位置火到達的時間,只要Jor提早到達便可,由於最開始可能有多個地方有火,因此bfs_fire不是單元BFS而是多元BFS,其實多元BFS也沒什麼深奧的,就是最開始隊列要加入多個時間爲0的起點便可,而BFS_Jor只要知足到達位置時間小於火到達時間便可加入隊列。spa
#include <iostream> #include <queue> #include <cstring> #include <algorithm> #include <cmath> #define fastio ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL) using namespace std; typedef long long ll; typedef pair<int, int> PII; const int N = 1010; const int INF = 0x3f3f3f3f; const double eps = 1e-6; const int mod = 998244353; struct node { int arrive_T, x, y; }; int dis[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; int n, m, ans, out = 0; int tim[N][N]; //存(i,j)火到達的時間 char a[N][N]; //存輸入圖 bool vis[N][N]; bool check(int i, int j) //判斷邊界條件 { if (i >= 1 && i <= n && j >= 1 && j <= m && a[i][j] != '#' && !vis[i][j]) return true; return false; } void bfs_fire() { memset(tim, INF, sizeof tim); memset(vis, false, sizeof vis); queue<node> q; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) if (a[i][j] == 'F') { vis[i][j] = true, tim[i][j] = 0; q.push({0, i, j}); } while (q.size()) { node t = q.front(); q.pop(); for (int k = 0; k < 4; k++) { int i = t.x + dis[k][0], j = t.y + dis[k][1]; if (check(i, j)) { q.push({t.arrive_T + 1, i, j}); vis[i][j] = true, tim[i][j] = t.arrive_T + 1; } } } } void bfs_Joe() { memset(vis, false, sizeof vis); queue<node> q; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) if (a[i][j] == 'J') { q.push({0, i, j}), vis[i][j] = true; break; } if (q.size()) break; } while (q.size()) { node t = q.front(); q.pop(); if (t.x == 1 || t.x == n || t.y == 1 || t.y == m) { cout << t.arrive_T + 1 << endl; out++; return; } for (int k = 0; k < 4; k++) { int i = t.x + dis[k][0], j = t.y + dis[k][1]; if (check(i, j) && t.arrive_T + 1 < tim[i][j]) //只要知足到達位置時間小於火到達時間便可加入隊列 { q.push({t.arrive_T + 1, i, j}); vis[i][j] = true; } } } } int main() { fastio; int T; cin >> T; while (T--) { cin >> n >> m; ans = 0, out = 0; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) cin >> a[i][j]; bfs_fire(); bfs_Joe(); if (!out) cout << "IMPOSSIBLE" << endl; } return 0; }