题目: POJ 3984 迷宫问题
经典的BFS求图的最短路径题目,从起点开始,按题目要求,对当前节点(x,y)向4个方向进行拓展,判断拓展的节点是否满足条件(是否越界,是否有被访问过,是否能走)
若满足条件,将这些节点push() 入队,(x,y)拓展完成后pop()出队,继续取队列中的头节点为当前节点继续拓展,直到拓展到中点,即按节点中储存的前驱节点信息反向
推到起始节点并输出。 代码中使用了结构体来储存节点的一些信息,如:该节点的前驱节点坐标,是否能走,是否被访问过等。
代码如下:
#include<cstdio>
#include<iostream>
#include<queue>
using namespace std;
const int N=5;
const int dirx[4]={1,0,-1,0};//定义x的四个方向
const int diry[4]={0,1,0,-1};//定义y的四个方向
int x,y;
struct inf{
int px,py;//该点的前驱
int x,y;//坐标
int val;//能否通行
bool vis;//是否被访问, 1为已访问 0为未访问
};
inf d[N][N];
queue<inf> q; //保存遍历的点的顺序
void output(int x,int y) //输出子程序,倒序输出
{
if(x == 0 && y == 0) //终值
{
printf("(%d , %d)\n",x,y);
return;
}
output(d[x][y].px,d[x][y].py); //当前点不为(0,0) 继续搜索当前点的前驱结点
printf("(%d , %d)\n",x,y);
return;
};
void bfs() //广搜求最短路径
{
inf head;
int dx,dy;
d[0][0].vis=1;//(0,0)起点被访问
q.push((d[0][0]));//(0,0)入队
while(!q.empty())//队列不为空,继续循环
{
head=q.front();//取队头节点为当前节点
q.pop();//将队头出队
for(int i = 0;i < 4;i++) //向4个方向搜索后继节点
{
dx = head.x + dirx[i]; //可能的后继节点x坐标
dy = head.y + diry[i]; //可能的后继节点y坐标
if(dx < 0 || dy < 0 || dx > N || dy > N || d[dx][dy].val == 1) //判断后继节点是否越界或是一堵墙
continue;
if(d[dx][dy].vis == 0) //判断该后继节点是否被访问过
{
d[dx][dy].px = head.x; //后继节点的前驱节点为当前点
d[dx][dy].py = head.y;//同上
d[dx][dy].vis = 1; //标记为已访问
q.push(d[dx][dy]); //入队
}
if(dx == N-1 && dy == N-1)//搜索到了终点
{
output(dx,dy);//输出
return;
}
}
}
return;
}
int main()
{
for(int i = 0; i < N; i++)
{
for(int j = 0; j < N; j++)
{
scanf("%d",&d[i][j].val);//读入
d[i][j].x=i;//对各点信息初始化
d[i][j].y=j;
d[i][j].vis=0;
d[i][j].px=0;
d[i][j].py=0;
}
}
while(!q.empty()) //初始化队列
q.pop();
bfs(); //开始广搜
return 0;
}
以上代码是借鉴了博主EricGuo55的代码并添加了自己的小修改,仅供个人学习以及记录,如有侵权请联系删除 谢谢!