广度优先搜索,就是从一个节点开始搜索,搜索完毕后,再从它四周的未访问过的节点开始搜索,重复之前的操作.它就像水波扩散一样.
广搜的基础问题就是:给定一个迷宫,求最短多少步可以走到终点.其中'S'为起点,'T'为终点,'.'为道路,'*'为墙.很显然有墙的地方就不能走.为了我们在搜索完一个节点后将节点周围的点存起来准备搜索,同时又不能打乱搜索的顺序,所以我们可以用queue来存储.
基本模板为:
#include <iostream>
#include <queue>
#define maxn 100 + 5
#define maxm 100 + 5
using namespace std;
const int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};//表示4个方向:上下左右
struct node{
int x, y, step;//分别表示纵坐标、横坐标和当前的步数
node(){}
node(const int &_x, const int &_y, const int &_step){
x = _x;
y = _y;
step = _step;
}
};
int n, m;//分别为行数,列数
char g[maxn][maxm];//用于存图
int sx, sy, tx, ty;//分别是起点的坐标和终点的坐标
bool vis[maxn][maxm];//用于记录某个点是否访问过
bool check(const int &x, const int &y){
return 0 < x && x <= n && 0 < y && y <= m;//判断当前坐标是否在图内
}
int bfs(const int &sx, const int &sy, const int &ex, const int &ey){
queue<node> q;//用于存将要搜索的坐标的信息
q.push(node(sx, sy, 0));//将起点放入队列
vis[sx][sy] = true;//将起点标记为已访问
node now;
int tx, ty;
while(!q.empty()){
now = q.front();//每次取队首的值
q.pop();//删除队首的值
for(int i = 0; i < 4; i++){
tx = now.x + dir[i][0];
ty = now.y + dir[i][1];//tx,ty分别表示下一步的坐标
if(check(tx, ty) && !vis[tx][ty] && g[tx][ty] != '*'){
if(tx == ex && ty == ey){
return now.step + 1;//先到达tx,ty的就是最少步数
}else{
q.push(node(tx, ty, now.step + 1));//将下一步放入队列准备对其进行搜索
vis[tx][ty] = true;//将下一步标记为已访问
}
}
}
}
}
int main(){
cin >> n >> m;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++){
cin >> g[i][j];
if(g[i][j] == 'S'){
sx = i;
sy = j;
}//记录起点坐标
if(g[i][j] == 'T'){
tx = i;
ty = j;
}//记录终点坐标
}
cout << bfs(sx, sy, tx, ty) << endl;
return 0;
}
BFS是个很有用的算法.