您的位置:首页 > 其它

POJ1915(Knight Moves,双向BFS)

2016-08-22 13:56 387 查看
题目链接:http://poj.org/problem?id=1915

用两个队列 Q和 P,Q用来储存正向搜索的节点,P用来储存逆向搜索的节点;在地图中进行染色,正向搜索到的节点染色为1,逆向搜索到的节点染色为2,当正向搜索到染色为2的节点时或者逆向搜索到染色为1的节点时表示两者相遇;还要标从起点(或终点)到当前位置所需要的步数,当相遇的时候起点到该点的距离加上重点到该点的距离就是起点到终点的距离。

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;

const int dx[8] = {-1,-2,-2,-1,1,2,2,1};
const int dy[8] = {-2,-1,1,2,2,1,-1,-2};
struct node
{
int x, y;
node() {}
node(int x, int y):x(x), y(y) {}
};
node st, en;
int vis[330][330];
int step[330][330];
int n;
queue<node> Q;
queue<node> P;

bool in(int x, int y)
{
if (x < 0 || x >= n || y < 0 || y >= n)
return false;
return true;
}

int BFS()
{
if (st.x == en.x && st.y == en.y)
return 0;
while (!Q.empty()) Q.pop(); //正向队列
while (!P.empty()) P.pop(); //逆向队列

Q.push(st);
P.push(en);
vis[st.x][st.y] = 1;
vis[en.x][en.y] = 2;
while (!Q.empty() || !P.empty())
{
if (!Q.empty())
{
node now = Q.front();
Q.pop();
for (int i=0; i<8; i++)
if (in(now.x+dx[i],now.y+dy[i]))
{
node New = node(now.x+dx[i], now.y+dy[i]);
if (vis[New.x][New.y] == 2)  //相遇
return step[now.x][now.y] + step[New.x][New.y] + 1;
else if (vis[New.x][New.y] == 0)
{
vis[New.x][New.y] = 1;
step[New.x][New.y] = step[now.x][now.y] + 1;
Q.push(New);
}
}
}
if (!P.empty())
{
node now = P.front();
P.pop();
for (int i=0; i<8; i++)
if (in(now.x+dx[i],now.y+dy[i]))
{
node New = node(now.x+dx[i], now.y+dy[i]);
if (vis[New.x][New.y] == 1)  //相遇
return step[now.x][now.y] + step[New.x][New.y] + 1;
else if (vis[New.x][New.y] == 0)
{
vis[New.x][New.y] = 2;
step[New.x][New.y] = step[now.x][now.y] + 1;
P.push(New);
}
}
}
}
}

int main()
{
int t;

scanf("%d",&t);
for (int cnt = 0; cnt<t; cnt++)
{
int sx, sy, tx, ty;

scanf("%d",&n);
scanf("%d%d%d%d",&sx,&sy,&tx,&ty);
st = node(sx,sy);
en = node(tx,ty);
memset(vis,0,sizeof(vis));
memset(step,0,sizeof(step));
printf("%d\n",BFS());
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: