UVa 11624 大火蔓延的迷宫

https://vjudge.net/problem/UVA-11624

题意:
有一个大火蔓延的迷宫,迷宫中有障碍格,而所有着火的格子都会往四周蔓延。求出到达边界格子时的最短时间。

思路:
复杂了一点的迷宫。

在bfs之前,我们首先需要计算出火势蔓延的情况,火势每次向四周蔓延一个格子,所以这也是一个最短路问题,也用一次bfs,计算出每个空白格子着火时的时间。这样,当我们第二次bfs去计算走出迷宫的时间时,对于每一个可走的格子,我们只需要判断在此时该格子是否着火,如果还未着火,则该格子是可以走的。

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<queue>
  4 #include<cstring>
  5 using namespace std;
  6
  7 const int maxn = 1000 + 5;
  8
  9 int map[maxn][maxn];
 10 int fire[maxn][maxn];
 11 int vis[maxn][maxn];
 12
 13 int dx, dy;
 14 int n, m;
 15
 16 int sx[] = { 0, 0, 1, -1 };
 17 int sy[] = { 1, -1, 0, 0 };
 18
 19
 20 struct node
 21 {
 22     int x, y;
 23     int t;
 24 };
 25
 26 void bfs1()
 27 {
 28     memset(fire, -1, sizeof(fire));
 29     queue<node> Q;
 30     for (int i = 0; i < n;i++)
 31     for (int j = 0; j < m; j++)
 32     {
 33         if (map[i][j] == -1)
 34         {
 35             node p;
 36             p.x = i;
 37             p.y = j;
 38             p.t = 1;
 39             Q.push(p);
 40             fire[i][j] = 1;
 41         }
 42     }
 43     while (!Q.empty())
 44     {
 45         node p = Q.front();
 46         Q.pop();
 47         for (int k = 0; k < 4; k++)
 48         {
 49             int x = p.x + sx[k];
 50             int y = p.y + sy[k];
 51             if (x < 0 || x >= n || y < 0 || y >= m)  continue;
 52             if (map[x][y] != 1)     continue;
 53             if (fire[x][y] != -1)   continue;
 54             fire[x][y] = p.t + 1;
 55             node u;
 56             u.x = x;
 57             u.y = y;
 58             u.t = p.t + 1;
 59             Q.push(u);
 60         }
 61     }
 62 }
 63
 64
 65 int bfs2()
 66 {
 67     memset(vis, 0, sizeof(vis));
 68     queue<node> Q;
 69     node p;
 70     p.x = dx;
 71     p.y = dy;
 72     p.t = 1;
 73     Q.push(p);
 74     vis[dx][dy] = 1;
 75     while (!Q.empty())
 76     {
 77         node p = Q.front();
 78         Q.pop();
 79         if (p.x == 0 || p.x == n - 1 || p.y == 0 || p.y == m - 1)  return p.t;
 80         for (int k = 0; k < 4; k++)
 81         {
 82             int x = p.x + sx[k];
 83             int y = p.y + sy[k];
 84             if (vis[x][y])   continue;
 85             if (x < 0 || x >= n || y < 0 || y >= m)  continue;
 86             if (map[x][y] != 1)   continue;
 87             if (fire[x][y]!=-1 && p.t + 1 >= fire[x][y])   continue;
 88             node u;
 89             u.x = x;
 90             u.y = y;
 91             u.t = p.t + 1;
 92             Q.push(u);
 93             vis[x][y] = 1;
 94         }
 95     }
 96     return -1;
 97 }
 98
 99
100 int main()
101 {
102     ios::sync_with_stdio(false);
103     //freopen("D:\\txt.txt", "r", stdin);
104     int T;
105     char c;
106     cin >> T;
107     while (T--)
108     {
109         cin >> n >> m;
110         for (int i = 0; i < n;i++)
111         for (int j = 0; j < m; j++)
112         {
113             cin >> c;
114             if (c == ‘#‘)  map[i][j] = 0;
115             else if (c == ‘F‘)  map[i][j] = -1;
116             else if (c == ‘J‘)
117             {
118                 map[i][j] = 1;
119                 dx = i;
120                 dy = j;
121             }
122             else map[i][j] = 1;
123         }
124
125         bfs1();
126         int ans=bfs2();
127         if (ans == -1)  cout << "IMPOSSIBLE" << endl;
128         else cout << ans << endl;
129     }
130 }
时间: 2024-10-19 14:03:54

UVa 11624 大火蔓延的迷宫的相关文章

uva 11624 大火蔓延的迷宫 Fire!(两次bfs)

 题目:一个平面迷宫中有一个人,迷宫中有些点起火了,火和人每个单位时间只能向相邻的格子移动, 其中有一些空间被墙壁占据,问这个人在不背或烧到的情况下,离开迷宫的最快时间. 思路是先用bfs预处理每个格子起火的时间,在来一次bfs走迷宫,入队时判断着火事件和父节点时间大小关系 代码如下: #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iost

uva 11624 Fire!(多源BFS)

uva 11624 Fire! 题目大意:J在迷宫里工作,有一天迷宫起火了,火源有多处.每过一秒,火源都会向四个方向蔓延,J也会向四个方向移动,问J能不能跑出去,能的话输出他跑出去的最短时间,否则输出"IMPOSSIBLE" 解题思路:先进行一次BFS,找出每一点火焰蔓延到该处的最短时间.然后根据这张"火势图",对J的行进路线进行BFS.注意J在边缘的时候,以及没有火源的时候. #include <cstdio> #include <cstring

UVA 11624 - Fire!(BFS)

UVA 11624 - Fire! 题目链接 题意:一个迷宫,一些格子着火了,火每秒向周围蔓延,现在J在一个位置,问他能走出迷宫的最小距离 思路:BFS2次,第一次预处理每个位置着火时间,第二次根据这个再BFS一次 代码: #include <cstdio> #include <cstring> #include <queue> using namespace std; const int d[4][2] = {0, 1, 1, 0, 0, -1, -1, 0}; co

UVa 11624 Fire!(着火了!)

p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: "Times New Roman"; font-size: 10.5000pt } h3 { margin-top: 5.0000pt; margin-bottom: 5.0000pt; text-align: left; font-family: 宋体; font-weight: bold; font-size: 1

BFS(两点搜索) UVA 11624 Fire!

题目传送门 1 /* 2 BFS:首先对火搜索,求出火蔓延到某点的时间,再对J搜索,如果走到的地方火已经烧到了就不入队,直到走出边界. 3 */ 4 /************************************************ 5 Author :Running_Time 6 Created Time :2015-8-4 8:11:54 7 File Name :UVA_11624.cpp 8 ****************************************

UVA 11624 UVA 10047 两道用 BFS进行最短路搜索的题

很少用bfs进行最短路搜索,实际BFS有时候挺方便得,省去了建图以及复杂度也降低了O(N*M): UVA 11624 写的比较挫 #include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; struct node{ int ft; int sta; }flo[1010][1010]; int vis[1010][1010]; st

UVa 11624 Fire!(BFS 逃离火灾)

题意   n*m的迷宫中有一些着火点  每个着火点上下左右相邻的非墙点下一秒也将成为一个着火点  Joe每秒能向相邻的点移动一步  给你所有着火点的位置和Joe的位置  问Joe逃离这个迷宫所需的最小时间 可以先一遍bfs把每个点的最早着火时间存起来   只有Joe到达该点的时间小于这个时间Joe才能走这个点   只需要对Joe所在的点为起点再来一次bfs就行了   需要注意的是开始可能有多个着火点  我开始以为只有一个着火点被坑了好久 v[i][j]第一遍bfs记录点i,j的最早着火时间  第

(简单) UVA 11624 Fire! ,BFS。

Description Joe works in a maze. Unfortunately, portions of the maze have caught on fire, and the owner of the maze neglected to create a fire escape plan. Help Joe escape the maze. Given Joe's location in the maze and which squares of the maze are o

uva 11624 Fire! 【 BFS 】

按白书上说的,先用一次bfs,求出每个点起火的时间 再bfs一次求出是否能够走出迷宫 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<queue> 6 #include<vector> 7 using namespace std; 8 9 const int maxn = 1005; 10 cons