POJ1915(双向广搜)

http://poj.org/problem?id=1915

#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
using namespace std;
typedef struct point{
    int x, y;
    int moves;
}point;

queue<point> Q[2];
bool mp[2][305][305];
int mov[2][305][305];
int dir[8][2] = {{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2}};
int n;

int dbfs(point s,point e)
{
    //起点终点相同
    if(s.x == e.x && s.y == e.y)
        return 0;

    int inx = 0;
    mp[0][s.x][s.y] = 1;
    mp[1][e.x][e.y] = 1;

    point head, t, tail;
    Q[0].push(s);
    Q[1].push(e);

    while(!Q[0].empty() || !Q[1].empty())
    {
        inx = (inx ^ 1);  //改变搜索队列
        int siz = Q[inx].size();

        //单队列bfs
        for(int j = 0;j < siz;j ++)
        {
            head = Q[inx].front();
            Q[inx].pop();

            //另一个队列访问过此点了  则说明相遇
            if(mp[inx^1][head.x][head.y])
                return mov[0][head.x][head.y] + mov[1][head.x][head.y];

            for(int i = 0;i < 8;i ++)
            {
                int dx = head.x + dir[i][0];
                int dy = head.y + dir[i][1];

                if(dx < 0 || dy < 0 || dx >= n || dy >= n || mp[inx][dx][dy]) continue;

                t.x = dx;
                t.y = dy;
                t.moves = head.moves + 1;

                mp[inx][dx][dy] = true;
                mov[inx][dx][dy] = head.moves + 1;
                Q[inx].push(t);
            }
        }
    }
    return 0;
}
int main()
{
	int t;
	point s, e;
	cin >> t;
	while(t --)
    {
        scanf("%d",&n);
        scanf("%d%d%d%d",&s.x,&s.y,&e.x,&e.y);
        memset(mp,0,sizeof(mp));
        memset(mov,0,sizeof(mov));

        while(!Q[0].empty())
            Q[0].pop();

        while(!Q[1].empty())
            Q[1].pop();

        s.moves = 0;
        e.moves = 0;

        cout << dbfs(s,e) << '\n';
    }
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Soul_97/article/details/81628960
今日推荐