UVA_11624 Fire! 【BFS】

一、题面

二、题意分析

一个迷宫中,有一个人Joe和一个或多个起火点,起火点可以蔓延,人可以走动,都只能走4个方向,问人能走出去的最少步数,如果不能输出不可能。很多大佬说是两遍BFS,先一遍火,记录所有火蔓延到次位置的时间,然后再一遍BFS,让Joe去走,只要满足他到该点时,火还未蔓延至此就可以。我一开始就死磕的让火的蔓延与人走同步,但后来发现很多坑!!!后来A了,总结一下,在同步的时候其实需要控制的也是时间,只不过现在的时间是通过控制每次BFS访问的位置的个数来控制的,当Joe在某个时刻可能走的点都访问完后,那么火就蔓延一次,下一次Joe走的时候,要先判断一下,之前入队列的点是否在这一时刻还合法,然后继续访问队列中的其他点,再进行下一层的遍历。最终可得到最终结果。

三、AC代码

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <queue>
  5 using namespace std;
  6 const int MAXN = 1e3;
  7 int R, C;
  8 bool Maze[MAXN+3][MAXN+3];
  9 bool visited[MAXN+3][MAXN+3];
 10 char S[MAXN+3];
 11 const int dx[] = {0, 0, 1, -1};
 12 const int dy[] = {1, -1, 0, 0};
 13 
 14 struct Point
 15 {
 16     int x, y;
 17     int step;
 18     Point(){};
 19     Point(int a, int b)
 20     {
 21         x = a, y = b;
 22     }
 23 };
 24 queue<Point> FQ;
 25 int BFS(Point J)
 26 {
 27     memset(visited, 0, sizeof(visited));
 28     queue<Point> JQ;
 29     Point tj , tf, t;
 30     int x, y, Cnt = J.step;
 31     JQ.push(J);
 32     while(!JQ.empty())
 33     {
 34         tj = JQ.front();
 35 
 36         if(tj.step > Cnt)
 37         {
 38             Cnt = tj.step;
 39             int L = FQ.size();
 40             for(int i = 0; i < L; i++)
 41             {
 42                 t = FQ.front();
 43                 FQ.pop();
 44                 for(int j = 0; j < 4; j++)
 45                 {
 46                     x = t.x + dx[j];
 47                     y = t.y + dy[j];
 48 
 49                     if(Maze[x][y] == 1 && x >= 0 && x < R && y >= 0 && y < C)
 50                     {
 51 
 52                         Maze[x][y] = 0;
 53                         FQ.push(Point(x, y));
 54                     }
 55                 }
 56             }
 57         }
 58         JQ.pop();
 59         if(Maze[tj.x][tj.y] == 0)
 60             continue;
 61         for(int i = 0; i < 4; i++)
 62         {
 63             t.x = tj.x + dx[i];
 64             t.y = tj.y + dy[i];
 65             t.step = tj.step+1;
 66             if(t.x < 0 || t.x >= R || t.y < 0 || t.y >= C)
 67             {
 68                 return t.step;
 69             }
 70             if(Maze[t.x][t.y] == 1 && visited[t.x][t.y] == 0)
 71             {
 72                 visited[t.x][t.y] = 1;
 73                 JQ.push(t);
 74             }
 75         }
 76     }
 77     return -1;
 78 }
 79 
 80 int main()
 81 {
 82     //freopen("input.txt", "r", stdin);
 83     //freopen("output.txt", "w", stdout);
 84     int T, Ans;
 85     scanf("%d", &T);
 86     int K = 0;
 87     while(T--)
 88     {
 89         K++;
 90         memset(Maze, 0, sizeof(Maze));
 91         while(!FQ.empty())
 92             FQ.pop();
 93         scanf("%d %d", &R, &C);
 94         Point J, F;
 95         for(int i = 0; i < R; i++)
 96         {
 97             scanf("%s", S);
 98             for(int j = 0; j < C; j++)
 99             {
100                 if(S[j] == '#')
101                     Maze[i][j] = 0;
102                 else if(S[j] == '.')
103                     Maze[i][j] = 1;
104                 else if(S[j] == 'J')
105                 {
106                     J.x = i, J.y = j;
107                     Maze[i][j] = 1;
108                 }
109                 else if(S[j] == 'F')
110                 {
111                     F.x = i, F.y = j;
112                     Maze[i][j] = 0;
113                     FQ.push(F);
114                 }
115             }
116         }
117         visited[J.x][J.y] = 1;
118         J.step  = 0;
119         Ans = BFS(J);
120         if(Ans == -1)
121         {
122             printf("IMPOSSIBLE\n");
123         }
124         else
125             printf("%d\n", Ans);
126     }
127     return 0;
128 }
View Code

 

posted @ 2018-11-24 20:36  Dybala21  阅读(107)  评论(0编辑  收藏  举报