POJ 1915 Knight Moves(双向BFS)

题目链接:POJ 1915 Knight Moves

双向BFS的优点上篇文章有。vis = 2表示从终点开始的搜索已经达到过这一点,vis = 1表示从源点开始的搜索已经达到过这一点,vis = 0表示没搜到过这一点。

一定要按层扩展,具体原因可以看这里,这篇博客还写了一个优化办法,我没看懂就没加,poj数据太水了,下午没按层扩展也过了。。

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

using namespace std;

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

struct Point
{
    int x, y, dis;
    Point(int x = 0, int y = 0, int dis = 0) : x(x), y(y), dis(dis) {};
};

int vis[MAX_N][MAX_N], dis[MAX_N][MAX_N];;
int fx[8] = {2, 2, -2, -2, 1, 1, -1, -1};
int fy[8] = {1, -1, 1, -1, 2, -2, 2, -2};

int n, res;
queue <Point> Qs, Qe;

void BFS()
{
    Point a;
    int dx, dy, now = 0;
    while(!Qs.empty() && !Qe.empty())
    {
        while(Qs.front().dis == now)
        {
            a = Qs.front();
            Qs.pop();
            for(int i = 0; i < 8; i++)
            {
                dx = a.x + fx[i], dy = a.y + fy[i];
                if(dx >= 0 && dy >= 0 && dx < n && dy < n && vis[dx][dy] != 1)
                {
                    if(vis[dx][dy] == 2)
                    {
                        res = a.dis + 1 + dis[dx][dy];
                        return ;
                    }
                    Qs.push(Point(dx, dy, a.dis + 1));
                    vis[dx][dy] = 1;
                    dis[dx][dy] = a.dis + 1;
                }
            }
        }
        while(Qe.front().dis == now)
        {
            a = Qe.front();
            Qe.pop();
            for(int i = 0; i < 8; i++)
            {
                dx = a.x + fx[i], dy = a.y + fy[i];
                if(dx >= 0 && dy >= 0 && dx < n && dy < n && vis[dx][dy] != 2)
                {
                    if(vis[dx][dy] == 1)
                    {
                        res = a.dis + 1 + dis[dx][dy];
                        return ;
                    }
                    Qe.push(Point(dx, dy, a.dis + 1));
                    vis[dx][dy] = 2;
                    dis[dx][dy] = a.dis + 1;
                }
            }
        }
        now++;
    }
}

int main()
{
    //freopen("in.txt", "r", stdin);
    int T;
    scanf("%d", &T);
    Point _start, _end;
    while(T--)
    {
        scanf("%d", &n);
        scanf("%d%d", &_start.x, &_start.y);
        scanf("%d%d", &_end.x, &_end.y);
        res = INF;
        memset(vis, 0, sizeof(vis));
        if(_start.x == _end.x && _start.y == _end.y)
        {
            printf("0\n");
            continue;
        }
        while(!Qs.empty())
            Qs.pop();
        while(!Qe.empty())
            Qe.pop();
        Qs.push(_start), Qe.push(_end);
        dis[_start.x][_start.y] = dis[_end.x][_end.y] = 0;
        vis[_start.x][_start.y] = 1;
        vis[_end.x][_end.y] = 2;
        BFS();
        printf("%d\n", res);
    }
    return 0;
}



你可能感兴趣的:(POJ 1915 Knight Moves(双向BFS))