两次BFS

原题链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2671
乔在迷宫里工作。不幸的是,迷宫的一部分着火了,迷宫的主人忽略了生火。
逃生计划。帮助乔逃离迷宫。
考虑到乔在迷宫里的位置和迷宫的哪个方格着火了,你必须先确定乔是否能离开迷宫
火向他扑来,他能跑多快。
乔和火每分钟移动一个正方形,垂直或水平(不是对角)。火向四面八方蔓延
从每个着火的广场。
乔可以从任何迷宫里出来迷宫边缘的正方形。
乔和火都没有
可以进入一个被墙占据的广场。

输入
输入的第一行包含一个整数,即测试数
接下来的案例。每个测试用例的第一行包含两个
整数r和c,用空格分隔,1≤r,c≤1000。这个
在测试用例的R行之后,每个都包含一行迷宫。每一行都包含
C字符,每个字符都是以下字符之一:
一堵墙
•,一个可通行的广场
•J,乔在迷宫中的初始位置,这是一个可以通过的正方形
•F,着火的正方形
每个测试用例中只有一个j。

输出
对于每个测试用例,如果joe不能在
火到达了他,或者是一个整数,给了乔最早的时间,几分钟内就能安全地离开迷宫。

Sample Input
2
4 4

#JF#
#…#
#…#
3 3

#J.
#.F
Sample Output
3
IMPOSSIBLE

个人心得:这题很难,参照了一下网上的思路:起火的地方并不是唯一,火势可以影响Joe的逃跑路线,但Joe的逃跑路线不能影响火势,所以这两个过程不可能出现在同一个BFS中
网上大佬的代码,码下来慢慢看
ac代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>

using namespace std;

struct node{
    int x, y, step;
    void setNode(int x, int y, int step){
        this->x = x;
        this->y = y;
        this->step = step;
    }
};
char maze[1005][1005];
int dis[1005][1005], n, m;
bool vis[1005][1005];
const int inf = 0x3f3f3f3f;
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};            

void bfs(int sx, int sy)
{
    queue<node> q;
    node tmp;
    memset(vis, 0, sizeof(vis));
    if(sx == -1){
        for(int i = 0; i < n; i++)
              for(int j = 0; j < m; j++)
                  if(maze[i][j] == 'F')
                {
                    tmp.setNode(i, j, 0);
                    q.push(tmp);
                    vis[i][j] = 1;
                    dis[i][j] = 0;
                }
    }else{
        tmp.setNode(sx, sy, 0);
        q.push(tmp);
        vis[sx][sy] = 1;
    }
    int x, y, step, ans;
    bool fg = false;
    while(!q.empty())
    {
        x = q.front().x;
        y = q.front().y;
        step = q.front().step;
        q.pop();
        if(maze[sx][sy]=='J'&&(x == n-1 || y == m-1 || x == 0 || y == 0)){
            fg = true;
            ans = step+1;                                                
        }
        for(int i = 0; i < 4; i++)
        {
            int nx = x + dx[i];
            int ny = y + dy[i];
            if(nx>=0&&nx<n&&ny>=0&&ny<m&&!vis[nx][ny]&&maze[nx][ny]!='#'){
                vis[nx][ny] = 1;
                if(maze[sx][sy]=='J'){
                      if(step+1 >= dis[nx][ny])continue;
                    else if(nx == n-1 || ny == m-1 || nx == 0 || ny == 0){
                        fg = true;
                        ans = step+2;
                    }
                }else dis[nx][ny] = min(dis[nx][ny], step+1);
                tmp.setNode(nx, ny, step+1);
                q.push(tmp);
            }
        }
        if(fg)break;
    }
    if(maze[sx][sy] == 'J')
          if(fg)printf("%d\n", ans);
        else printf("IMPOSSIBLE\n");
}

int main()
{
    int T, jx, jy;
    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++){
                  scanf("%c", &maze[i][j]);
                if(maze[i][j] == 'J'){
                    jx = i; jy = j;
                }
            }
            getchar();
        }
        memset(dis, inf, sizeof(dis));
        bfs(-1, -1);
        bfs(jx, jy);
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43602944/article/details/86688116