POJ 1915 Knight Moves(双向BFS)

来源:互联网 发布:java微信小程序开发 编辑:程序博客网 时间:2024/05/22 07:06

题目链接: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;}



0 0