UVa 11624 Fire!(多源BFS)

题目链接:UVa 11624  Fire!

要是把人和火一起考虑就会感觉很乱,可以分开考虑,然后计算某个边界点谁先到,人先到就表示人可以逃出去,然后取这些值中那个最小的,这里有一个问题,会不会在途中人和火相遇,然后人比火先到达某个边界点,仔细想想就会发现不会有这种情况,用反证法,如果相遇,那么某个边界点至少是人和火同时到。

所有火都需要都加入队列。

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

using namespace std;

struct Point
{
    int x, y;
    Point (int x, int y) : x(x), y(y) {};
    Point(){};
};
const int MAX_N = 1000 + 10;
int vis1[MAX_N][MAX_N], vis2[MAX_N][MAX_N],dis1[MAX_N][MAX_N], dis2[MAX_N][MAX_N];
char _map[MAX_N][MAX_N];
int fx[4] = {0, 0, 1, -1};
int fy[4] = {1, -1, 0, 0};

int R, C;
queue <Point> Q;

void BFS1()
{
    int dx, dy;
    while(!Q.empty())
    {
        Point a = Q.front();
        Q.pop();
        for(int i = 0; i < 4; i++)
        {
            dx = a.x + fx[i], dy = a.y + fy[i];
            if(dx >= 0 && dx < R && dy >= 0 && dy < C && _map[dx][dy] != '#' && !vis1[dx][dy])
            {
                dis1[dx][dy] = dis1[a.x][a.y] + 1;
                vis1[dx][dy] = 1;
                Q.push(Point(dx, dy));
            }
        }
    }
}

void BFS2()
{
    int dx, dy;
    while(!Q.empty())
    {
        Point a = Q.front();
        Q.pop();
        for(int i = 0; i < 4; i++)
        {
            dx = a.x + fx[i], dy = a.y + fy[i];
            if(dx >= 0 && dx < R && dy >= 0 && dy < C && _map[dx][dy] != '#' && !vis2[dx][dy])
            {
                dis2[dx][dy] = dis2[a.x][a.y] + 1;
                vis2[dx][dy] = 1;
                Q.push(Point(dx, dy));
            }
        }
    }
}
int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        memset(vis1, 0, sizeof(vis1)), memset(vis2, 0, sizeof(vis2));
        vector <Point> fires;
        Point Joe;
        scanf("%d%d", &R, &C);
        for(int i = 0; i < R; i++)
        {
            scanf("%s", _map[i]);
            for(int j = 0; j < C; j++)
            {
                if(_map[i][j] == 'F')
                    fires.push_back(Point(i, j));
                else if(_map[i][j] == 'J')
                    Joe.x = i, Joe.y = j;
            }
        }
        int _size = fires.size();
        for(int i = 0; i < _size; i++)
        {
            Q.push(fires[i]);
            dis2[fires[i].x][fires[i].y] = 0;
            vis2[fires[i].x][fires[i].y] = 1;
        }
        BFS2();
        Q.push(Joe);
        dis1[Joe.x][Joe.y] = 0;
        vis1[Joe.x][Joe.y] = 1;
        BFS1();
        int ans = MAX_N * MAX_N;
        for(int i = 0; i < R; i++)
        {
            if(vis1[i][0])
            {
               if(!vis2[i][0] || dis2[i][0] > dis1[i][0])
                    ans = min(ans, dis1[i][0]);
            }
            if(vis1[i][C - 1])
            {
               if(!vis2[i][C - 1] || dis2[i][C - 1] > dis1[i][C - 1])
                    ans = min(ans, dis1[i][C - 1]);
            }

        }
        for(int j = 0; j < C; j++)
        {
            if(vis1[0][j])
            {
                if(!vis2[0][j] || dis2[0][j] > dis1[0][j])
                    ans = min(ans, dis1[0][j]);
            }
            if(vis1[R - 1][j])
            {
                if(!vis2[R - 1][j] || dis2[R - 1][j] > dis1[R - 1][j])
                    ans = min(ans, dis1[R - 1][j]);
            }

        }
        if(ans == MAX_N * MAX_N)
            printf("IMPOSSIBLE\n");
        else
            printf("%d\n", ans + 1);
    }
    return 0;
}



你可能感兴趣的:(UVa 11624 Fire!(多源BFS))