kuangbin专题 专题一 简单搜索 Fire! UVA - 11624


 

题目链接:https://vjudge.net/problem/UVA-11624

题意:一个迷宫,可能有一个或者多个地方着火了,每过1个时间消耗,火会向四周蔓延,问Joe能不能逃出迷宫,只要走出迷宫边界就算逃出,火和Joe都不能透过墙。

思路:人和火源分别跑bfs,人一张地图,火源一张地图,跑各自能到达点的时间,火源可能有多个,
最后只需要判断迷宫的四个边中人和火源的时间消耗来得出最小答案,出不去输出“IMPOSSIBLE”,思路比较简单,代码稍微复杂点。


  1 #include <iostream>
  2 #include <cstring>
  3 #include<vector>
  4 #include<string>
  5 #include <cmath>
  6 #include <map>
  7 #include <queue>
  8 #include <algorithm>
  9 using namespace std;
 10 
 11 #define inf (1LL << 31) - 1
 12 #define rep(i,j,k) for(int i = (j); i <= (k); i++)
 13 #define rep__(i,j,k) for(int i = (j); i < (k); i++)
 14 #define per(i,j,k) for(int i = (j); i >= (k); i--)
 15 #define per__(i,j,k) for(int i = (j); i > (k); i--)
 16 
 17 const int N = 1010;
 18 int mv_x[] = { 0, 0, -1, 1 };
 19 int mv_y[] = { 1, -1, 0, 0 };
 20 char mp[N][N];
 21 int Fire[N][N]; //
 22 bool vis[N][N];
 23 int x[N];  //火源的x
 24 int y[N];  //火源的y
 25 int l;     //火源的个数
 26 int Joe[N][N];  //Joe
 27 int n, m;
 28 int pi, pj; //Joe的坐标
 29 
 30 struct node{
 31     int x, y, v;
 32 };
 33 
 34 inline void init(){
 35     rep(i, 1, n) rep(j, 1, m){
 36         Joe[i][j] = 0;
 37         Fire[i][j] = inf;
 38     }
 39 }
 40 
 41 inline void input(){
 42 
 43     l = 0;
 44     rep(i, 1, n) rep(j, 1, m){
 45         cin >> mp[i][j];
 46         
 47         //记录每个火源
 48         if (mp[i][j] == 'J') pi = i, pj = j;
 49         else if (mp[i][j] == 'F') x[l] = i, y[l++] = j;
 50     }
 51 }
 52 
 53 inline bool check(int x, int y){
 54     return x >= 1 && x <= n && y >= 1 && y <= m;
 55 }
 56 
 57 void bfs_p(){
 58 
 59     queue<node> que;
 60     Joe[pi][pj] = 1;
 61     que.push(node{ pi, pj, 1 });
 62 
 63     while (!que.empty()){
 64 
 65         node tmp = que.front();
 66         que.pop();
 67         rep__(p, 0, 4){
 68 
 69             int dx = tmp.x + mv_x[p];
 70             int dy = tmp.y + mv_y[p];
 71 
 72             if (check(dx, dy) && !Joe[dx][dy] && mp[dx][dy] != '#'){
 73                 Joe[dx][dy] = tmp.v + 1;
 74                 que.push(node{ dx, dy, tmp.v + 1 });
 75             }
 76         }
 77     }
 78 }
 79 
 80 void bfs_f(int fi, int fj){
 81 
 82     rep(i, 1, n) rep(j, 1, m) vis[i][j] = 0;
 83     queue<node> que;
 84 
 85     Fire[fi][fj] = 1;
 86     vis[fi][fj] = true;
 87     que.push(node{ fi, fj, 1 });
 88 
 89     while (!que.empty()){
 90 
 91         node tmp = que.front();
 92         que.pop();
 93         rep__(p, 0, 4){
 94 
 95             int dx = tmp.x + mv_x[p];
 96             int dy = tmp.y + mv_y[p];
 97 
 98             if (check(dx, dy) && !vis[dx][dy] && mp[dx][dy] != '#'){
 99                 vis[dx][dy] = true;
100 
101                 if (tmp.v + 1 < Fire[dx][dy])  //比较与之前的火源,哪个最先烧到这个点
102                     Fire[dx][dy] = tmp.v + 1, que.push(node{ dx, dy, tmp.v + 1 });
103 
104                 //    cout <<  "Fire[][] " <<  Fire[dx][dy] << endl;
105 
106             }
107         }
108     }
109 
110 
111 }
112 
113 void search_fire(){
114 
115     rep__(i, 0, l){
116         bfs_f(x[i], y[i]);
117     }
118 }
119 
120 void get_ans(){
121 
122     int ans = inf;
123 
124     //先把Fire地图所有的inf,也就是无法到达的点赋值为0,方便比较
125     rep(i, 1, n) rep(j, 1, m) if (Fire[i][j] == inf) Fire[i][j] = 0;
126 
127     //一种情况,Joe到达某点时间比Fire短,
128     //另一个情况,可能Fire到达不了那个点,于是Fire[x][y] == 0,所有有个特殊判断 Fire[x][y] == 0
129     
130     //下面就是四个边界情况了
131     rep(i, 1, n){
132         if (i == 1 || i == n){
133             rep(j, 1, m){
134                 if (Joe[i][j] < Fire[i][j] || (Fire[i][j] == 0 && Joe[i][j] != 0)) 
135                     ans = min(ans, Joe[i][j]);
136             }
137         }
138         else {
139             if (Joe[i][1] < Fire[i][1] || (Fire[i][1] == 0 && Joe[i][1] != 0)) 
140                 ans = min(ans, Joe[i][1]);
141 
142             if (Joe[i][m] < Fire[i][m] || (Fire[i][m] == 0 && Joe[i][m] != 0)) 
143                 ans = min(ans, Joe[i][m]);
144         }
145     }
146 
147     if (ans == inf) cout << "IMPOSSIBLE" << endl;
148     else cout << ans << endl;
149 }
150 
151 int main(){
152 
153     ios::sync_with_stdio(false);
154     cin.tie(0);
155 
156     int T;
157     cin >> T;
158 
159     rep(i, 1, T){
160 
161         cin >> n >> m;
162         init(); //初始化
163         input();  //输入
164         bfs_p();  //Joe的bfs
165         search_fire();  //所有火源的bfs
166         get_ans();  //得到答案
167     }
168 
169 
170     return 0;
171 }

 


作者:SSummerZzz,发布于:2019/07/11
原文:https://www.cnblogs.com/SSummerZzz/p/11164233.html