UVA 11624 (BFS)

版权声明:本文为博主原创文章,转载请说明出处。 https://blog.csdn.net/xianpingping/article/details/83041842

题目:一个平面迷宫中有一个人,迷宫中有些点起火了,火和人每个单位时间只能向相邻的格子移动,
            其中有一些空间被墙壁占据,问这个人在不背或烧到的情况下,离开迷宫的最快时间。
分析:搜索。迷宫中的最短路,首先就会想到bfs;并且bfs利用队列会使状态空间按时间顺序分层。
            而火的扩散过程正好符合这个时间的层次。所以我们会想到,利用两个队列,一个储存人的状态,
            一个储存火的状态。按照时间顺序,先更新火蔓延的节点,再扩展人能到达的节点。
            通过分析,我们发现这两个队列可以合并,只须初始化的时候,按照火节点然后是人的顺序入队即可。
           (节点中加入一个是否是火节点的判断,就可以两种节点按不同的细节处理)
注意:时间是指走出迷宫的时间,到达边界后要加1;初始节点的判断。

代码:

#include<bits/stdc++.h>
using namespace std;
const int MAX = 1010;
int m, n;
char mp[MAX][MAX];
int fire[MAX][MAX];     //火
int people[MAX][MAX];   //人
int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
queue<pair<int, int> > Q;
void BFS_fire()
{
    memset(fire, -1, sizeof(fire));
    while ( !Q.empty() )
    {
        Q.pop();
    }
    for (int i=0; i<n; i++)
    {
        for (int j=0; j<m; j++)
        {
            if (mp[i][j] == 'F')
            {
                fire[i][j] = 0;
                Q.push(make_pair(i, j));
            }
        }
    }
    while ( !Q.empty() )        //BFS火能烧到的地方,并且记录时间
    {
        pair<int, int> a;
        a = Q.front();
        Q.pop();
        int x = a.first;
        int y = a.second;
        for (int i=0; i<4; i++)
        {
            int xx = x + dir[i][0];
            int yy = y + dir[i][1];
            if (xx<0 || xx>=n || yy<0 || yy>=m) continue;
            if (fire[xx][yy] != -1) continue;        //被烧过
            if (mp[xx][yy] == '#') continue;       //有墙
            fire[xx][yy] = fire[x][y] + 1;      //记录时间
            Q.push(make_pair(xx, yy));
        }
    }
}
int BFS_people()
{
    memset(people, -1, sizeof(people));
    while ( !Q.empty() )
    {
        Q.pop();
    }
    for (int i=0; i<n; i++)
    {
        for (int j=0; j<m; j++)
        {
            if (mp[i][j] == 'J')
            {
                Q.push(make_pair(i, j));
                people[i][j] = 0;
            }
        }
    }
    while ( !Q.empty() )
    {
        pair<int, int> a;
        a = Q.front();
        Q.pop();
        int x = a.first;
        int y = a.second;
        if (x==0 || y==0 || x==n-1 || y==m-1)
        {
            return people[x][y]+1;
        }
        for (int i=0; i<4; i++)
        {
            int xx = x + dir[i][0];
            int yy = y + dir[i][1];
            if (xx<0 || xx>=n || yy<0 || yy>=m) continue;
            if (people[xx][yy] != -1) continue;      //已经走过
            if (mp[xx][yy] == '#') continue;           //有墙
            if (fire[xx][yy] != -1 && people[x][y]+1 >= fire[xx][yy]) continue;     //&&  之前是不能被火烧过  之后是到达的时间不能有火
            people[xx][yy] = people[x][y] + 1;      //更新时间
            Q.push(make_pair(xx, yy));
        }
    }
    return -1;
}
int main()
{
    int t;
    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++)
            {
                cin >> mp[i][j];
            }
        }
        BFS_fire();
        int ans = BFS_people();
        if(ans == -1)
        {
            printf("IMPOSSIBLE\n");
        }
        else
        {
            printf("%d\n",ans);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/xianpingping/article/details/83041842
今日推荐