广搜(BFS)
BFS的基本思想是:
首先访问初始点v并将其标志为已经访问。接着通过邻接关系将邻接点入队。然后每访问过一个顶点则出队。按照顺序(该顺序可以是顺时针也可以是逆时针自己规定的),访问每一个顶点的所有未被访问过的顶点直到所有的顶点均被访问过。
广度优先遍历类似与层次遍历。其特点是尽可能先对横向进行搜索,从指的出发点,按照该点的路径长度由短到长的顺序访问图中各顶点。
理解如下:
利用队列先进先出的性质(队列相当于一根管子:只有两个出口,一进一出,且进管子的顺序不能随意改变),从起点开始,将一步能到达的点全部存入队列,然后将队列中队首元素出队,执行与起点相同的操作,以此循环,直到到达终点或者队列为空,队列为空说明可以到达的点都已经遍历过了,也就是说没有路可以到达终点。
void BFS()
{ … …//初始化起点入队
while(!q.empty()) //判断队是否为空
{ … …//获取队首元素
if(... …)
{… …}//判断是否是终点
for(int i=0;i<4;i++)//四个方向
{
k.x=p.x+dir[i][0];
k.y=p.y+dir[i][1];
//向各个方向走一步
if(judge())//判断能不能走
{ … …//各种处理
vis[k.x][k.y]=1; //标记
q.push(k); //入队
}
}
}
}
迷宫:S为入口,G为出口
//迷宫的地图
/*
10 10
#S######.#
......#..#
.#.##.##.#
.#........
##.##.####
....#....#
.#######.#
....#.....
.####.###.
....#..#G#
*/
相关代码:
#include <iostream>
#include <string.h>
#include <queue>
using namespace std;
char a[201][201];
bool vis[201][201];//记录访问过没有 bool取值false和true,0为false,非0为true。
int dx[4] = {0,1,0,-1};
int dy[4] = {1,0,-1,0};
int N,M;
int sx,sy,ex,ey;
struct NODE
{
int x;
int y;
int step;
friend bool operator < (NODE n1,NODE n2)//自定义优先级。在优先队列中,优先级高的元素先出队列。
{
return n1.step > n2.step;// step 小的优先级高,需要先出队。
}
};
bool judge(int x,int y) //判断是否可以走,不能走返回1,否则返回0;
{
if( x<1 || y<1 || x>N || y>M ) //超出范围
return 1;
if( vis[x][y] ) //已经走过
return 1;
if( a[x][y]=='#' ) //为墙走不通
return 1;
return 0;
}
int bfs() //返回从(x,y)开始广搜,到右下角的最短步数,如果无法到达右下角,返回0
{
memset(vis,0,sizeof(vis)); //对vis中的元素全部赋值为0
priority_queue <NODE> q; //定义一个优先队列
NODE cur,next;
cur.x = sx;
cur.y = sy;
cur.step = 0;
vis[sx][sy] = true;
q.push(cur); //第一个元素入队
while(!q.empty())
{
cur = q.top(); //队首出队,注意不是front()
q.pop();
if(cur.x==ex && cur.y==ey) //到终点
return cur.step;
for(int i=0; i<4; i++)
{
int nx = cur.x + dx[i];//通过之前的定义可以得知,
int ny = cur.y + dy[i];//这可以保证将该点的上下左右四个点都访问一遍
if( judge(nx,ny) ) //判定
continue;
//可以走
next.x = nx;
next.y = ny;
next.step = cur.step + 1;
vis[nx][ny] = true;
q.push(next);
}
}
return -1;
}
int main()
{
cin>>N>>M;
for(int i=1; i<=N; i++) //输入
for(int j=1; j<=M; j++)
{
cin>>a[i][j];
if(a[i][j]=='G')
{
ex=i;
ey=j;
}
else if(a[i][j]=='S')
{
sx=i;
sy=j;
}
}
int step = bfs();
cout<<step<<endl;
return 0;
}