UVA 11624 (BFS)
阿新 • • 發佈:2018-12-15
題目:一個平面迷宮中有一個人,迷宮中有些點起火了,火和人每個單位時間只能向相鄰的格子移動, 其中有一些空間被牆壁佔據,問這個人在不背或燒到的情況下,離開迷宮的最快時間。 分析:搜尋。迷宮中的最短路,首先就會想到bfs;並且bfs利用佇列會使狀態空間按時間順序分層。 而火的擴散過程正好符合這個時間的層次。所以我們會想到,利用兩個佇列,一個儲存人的狀態, 一個儲存火的狀態。按照時間順序,先更新火蔓延的節點,再擴充套件人能到達的節點。 通過分析,我們發現這兩個佇列可以合併,只須初始化的時候,按照火節點然後是人的順序入隊即可。 (節點中加入一個是否是火節點的判斷,就可以兩種節點按不同的細節處理) 注意:時間是指走出迷宮的時間,到達邊界後要加1;初始節點的判斷。
程式碼:
#include<bits/stdc++.h> using namespace std; const int MAX = 1010; int m, n; char mp[MAX][MAX]; int fire[MAX][MAX]; //火 int people[MAX][MAX]; //人 int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; queue<pair<int, int> > Q; void BFS_fire() { memset(fire, -1, sizeof(fire)); while ( !Q.empty() ) { Q.pop(); } for (int i=0; i<n; i++) { for (int j=0; j<m; j++) { if (mp[i][j] == 'F') { fire[i][j] = 0; Q.push(make_pair(i, j)); } } } while ( !Q.empty() ) //BFS火能燒到的地方,並且記錄時間 { pair<int, int> a; a = Q.front(); Q.pop(); int x = a.first; int y = a.second; for (int i=0; i<4; i++) { int xx = x + dir[i][0]; int yy = y + dir[i][1]; if (xx<0 || xx>=n || yy<0 || yy>=m) continue; if (fire[xx][yy] != -1) continue; //被燒過 if (mp[xx][yy] == '#') continue; //有牆 fire[xx][yy] = fire[x][y] + 1; //記錄時間 Q.push(make_pair(xx, yy)); } } } int BFS_people() { memset(people, -1, sizeof(people)); while ( !Q.empty() ) { Q.pop(); } for (int i=0; i<n; i++) { for (int j=0; j<m; j++) { if (mp[i][j] == 'J') { Q.push(make_pair(i, j)); people[i][j] = 0; } } } while ( !Q.empty() ) { pair<int, int> a; a = Q.front(); Q.pop(); int x = a.first; int y = a.second; if (x==0 || y==0 || x==n-1 || y==m-1) { return people[x][y]+1; } for (int i=0; i<4; i++) { int xx = x + dir[i][0]; int yy = y + dir[i][1]; if (xx<0 || xx>=n || yy<0 || yy>=m) continue; if (people[xx][yy] != -1) continue; //已經走過 if (mp[xx][yy] == '#') continue; //有牆 if (fire[xx][yy] != -1 && people[x][y]+1 >= fire[xx][yy]) continue; //&& 之前是不能被火燒過 之後是到達的時間不能有火 people[xx][yy] = people[x][y] + 1; //更新時間 Q.push(make_pair(xx, yy)); } } return -1; } int main() { int t; scanf("%d", &t); while (t--) { scanf("%d %d", &n, &m); //getchar(); for (int i=0; i<n; i++) { for (int j=0; j<m; j++) { cin >> mp[i][j]; } } BFS_fire(); int ans = BFS_people(); if(ans == -1) { printf("IMPOSSIBLE\n"); } else { printf("%d\n",ans); } } return 0; }