POJ 2312 Battle City(优先队列 + BFS)

题目链接:POJ 2312 Battle City

打碎砖头需要两步,这里如果直接加到普通的队列中可以说是违反了BFS的规则,所以需要使用优先队列来选择当前队列中步数最少的那个,画画图就很明白了。

记得要清空队列。

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

using namespace std;

const int MAX_N = 300 + 10;
const int INF = (1 << 29);

struct Point
{
    int x, y, dis;
    friend bool operator < (Point a, Point b)
    {
        return a.dis > b.dis;
    }
    Point (int x, int y, int dis) : x(x), y(y), dis(dis) {};
    Point () {};
};
priority_queue <Point> Q;
int vis[MAX_N][MAX_N];
char _map[MAX_N][MAX_N];
int fx[4] = {0, 1, 0, -1};
int fy[4] = {1, 0, -1, 0};
int N, M, res;

void BFS()
{
    int dx, dy;
    Point a;
    while(!Q.empty())
    {
        a = Q.top();
        if(_map[a.x][a.y] == 'T')
        {
            res = a.dis;
            return ;
        }
        Q.pop();
        for(int i = 0; i < 4; i++)
        {
            dx = a.x + fx[i], dy = a.y + fy[i];
            if(dx >= 0 && dy >= 0 && dx < N && dy < M && !vis[dx][dy] && _map[dx][dy] != 'S' && _map[dx][dy] != 'R')
            {
                vis[dx][dy] = 1;
                if(_map[dx][dy] == 'B')
                    Q.push(Point(dx, dy, a.dis + 2));
                else
                    Q.push(Point(dx, dy, a.dis + 1));
            }
        }
    }
}

int main()
{
    while(scanf("%d%d", &N, &M), N + M)
    {
        memset(vis, 0, sizeof(vis));
        res = INF;
        for(int i = 0; i < N; i++)
        {
            scanf("%s", _map[i]);
            for(int j = 0; j < M; j++)
            {
                if(_map[i][j] == 'Y')
                {
                    vis[i][j] = 1;
                    Q.push(Point(i, j, 0));
                }
            }
        }
        BFS();
        if(res == INF)
            printf("-1\n");
        else
            printf("%d\n", res);
        while(!Q.empty())
            Q.pop();
    }
    return 0;
}


你可能感兴趣的:(POJ 2312 Battle City(优先队列 + BFS))