UVA 11624 BFS
题意
一个房间着火了,房间为N*M大,由墙壁#和空地 . 组成。空地可以被火烧着,火每一秒向周围四块拓展。问一个房间里的人能不能逃离房间,人和火都不能穿过墙。如果能够逃出,最短的逃出时间是多少。
分析
有可能多个地方有火,每个有火的地方都要进行dfs,标记空地块的最少多少秒会被火所点着。对人dfs,看人到达每一块空地块最短的时间。
最后检查边界的空地(边界的空地即说明有门可以走出房间)块上的人的时间,和火烧到的最短时间。如果人比火块,纪录答案,更新最小答案即可。
代码
1 /* When all else is lost the future still remains. */
2 /* You can be the greatest */
3 #define rep(X,Y,Z) for(int X=(Y);X<(Z);X++)
4 #define drep(X,Y,Z) for(int X=(Y);X>=(Z);X--)
5 #define fi first
6 #define se second
7 #define mk(X,Y) make_pair((X),(Y))
8 #define inf 0x3f3f3f3f
9 #define clr(X,Y) memset(X,Y,sizeof(X))
10 #define pb push_back
11 //head
12 #include <iostream>
13 #include <stdio.h>
14 #include <queue>
15 #include <algorithm>
16 #include <string>
17 #include <map>
18 #include <string.h>
19 using namespace std;
20 #define maxN 1010
21 int dx[] = {-1,0,1,0};
22 int dy[] = {0,-1,0,1};
23 int mp[maxN][maxN];
24 int val[2][maxN][maxN];
25 int mark[2][maxN][maxN];
26 void init(){
27 clr(mp,0);
28 clr(val,inf);
29 clr(mark,0);
30 return ;
31 }
32 void bfs(int x , int y ,int n , int m , int cnt){
33 queue<pair<int,int> > Q;
34 Q.push(mk(x,y));
35 mark[cnt][x][y] = 1;
36 val[cnt][x][y] = 0;
37 while(!Q.empty()){
38 int nx = Q.front().fi;
39 int ny = Q.front().se;
40 Q.pop();
41 rep(i,0,4){
42 int tx = nx + dx[i];
43 int ty = ny + dy[i];
44 if(!mp[tx][ty]) continue;
45 if(mark[cnt][tx][ty]) continue;
46 if(val[cnt][tx][ty] <= val[cnt][nx][ny] + 1) continue;
47 val[cnt][tx][ty] = val[cnt][nx][ny] + 1;
48 mark[cnt][tx][ty] = 1;
49 Q.push(mk(tx,ty));
50 }
51 }
52 return ;
53 }
54 int check(int n , int m){
55 int ans = -1;
56 rep(i,1,n+1) rep(j,1,m+1){
57 if(!mp[i][j]) continue;
58 if(i == 1 || i == n || j == 1 || j == m){
59 int fire_min = val[1][i][j];
60 if(val[0][i][j] < val[1][i][j]){
61 if(ans < 0) ans = val[0][i][j];
62 else ans = min(ans,val[0][i][j]);
63 }
64 }
65 }
66 return ans;
67 }
68 int main(){
69 int T;
70 scanf("%d",&T);
71 while(T--){
72 init();
73 int n , m ;
74 int px , py ;
75 vector<pair<int,int> > fire_set;
76 fire_set.clear();
77 char t;
78 scanf("%d %d\n",&n,&m);
79 rep(i,1,n+1){
80 rep(j,1,m+1){
81 scanf("%c",&t);
82 if(t == 'J') px = i , py = j;
83 if(t == 'F') fire_set.pb(mk(i,j));
84 mp[i][j] = (t=='#') ? 0 : 1;
85 }
86 getchar();
87 }
88 bfs(px,py,n,m,0);
89 int size = fire_set.size();
90 rep(i,0,size){
91 rep(i,1,n+1) rep(j,1,m+1) mark[1][i][j] = 0;
92 bfs(fire_set[i].fi,fire_set[i].se,n,m,1);
93 }
94 //mval(n,m);
95 int ans = check(n,m);
96 if(ans < 0) printf("IMPOSSIBLE\n");
97 else printf("%d\n",ans+1);
98
99 }
100 return 0;
101 }