HDOJ 3085 - Nightmare Ⅱ 【双向BFS】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3085

每一秒,对男孩和女孩同时经行bfs,男孩走3步,女孩走1步,走过的地方标记一下,同时判断与幽灵的曼哈顿距离。

#include <bits/stdc++.h>
using namespace std;
const int N = 810;
const int dx[4] = { 0, 0, 1, -1 }, dy[4] = { 1, -1, 0, 0 };
struct P{
    int x, y;
    P(int _x = 0, int _y = 0) :x(_x), y(_y){};
};
P z[3];
char maze[N][N];
queue<P> M, G, T;
int n, m, k;
void init()
{
    while (!M.empty()) M.pop();
    while (!G.empty()) G.pop();
    while (!T.empty()) T.pop();
}
void parse()
{
    for (int i = 0, t = 0; i < n; i++)
    {
        scanf("%s", maze[i]);
        for (int j = 0; j < m; j++)
        {
            if (maze[i][j] == 'M')
            {
                M.push(P(i, j));
            }
            else if (maze[i][j] == 'G')
            {
                G.push(P(i, j));
            }
            else if (maze[i][j] == 'Z')
            {
                z[t++] = P(i, j);
            }
        }

    }
}
bool valid(int x, int y)
{
    if (x < 0 || y < 0 || x >= n || y >= m) return false;
    if (maze[x][y] == 'X') return false;
    if (abs(x - z[0].x) + abs(y - z[0].y) <= 2 * k) return false;
    if (abs(x - z[1].x) + abs(y - z[1].y) <= 2 * k) return false;
    return true;
}
bool bfs(queue<P> &N, int step, char c1, char c2)
{
    while (step--)
    {
        T = N;
        while (!T.empty())
        {
            P cur = T.front();
            T.pop();
            N.pop();
            if (!valid(cur.x, cur.y)) continue;
            for (int i = 0; i < 4; i++)
            {
                int nx = cur.x + dx[i], ny = cur.y + dy[i];
                if (valid(nx, ny) && maze[nx][ny] != c2)
                {
                    if (maze[nx][ny] == c1) return true;
                    maze[nx][ny] = c2;
                    N.push(P(nx, ny));
                }
            }

        }
    }
    return false;
}
int solve()
{
    k = 0;
    while (!M.empty() && !G.empty())
    {
        k++;
        bool ok1 = bfs(M, 3, 'G', 'M');
        bool ok2 = bfs(G, 1, 'M', 'G');
        if (ok1 || ok2)
            return k;
    }
    return -1;
}
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        init();
        cin >> n >> m;
        parse();
        cout << solve() << endl;
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/xiaoguapi/p/10453447.html