算法模板:广度优先搜索BFS

        广度优先搜索,就是从一个节点开始搜索,搜索完毕后,再从它四周的未访问过的节点开始搜索,重复之前的操作.它就像水波扩散一样.

        广搜的基础问题就是:给定一个迷宫,求最短多少步可以走到终点.其中'S'为起点,'T'为终点,'.'为道路,'*'为墙.很显然有墙的地方就不能走.为了我们在搜索完一个节点后将节点周围的点存起来准备搜索,同时又不能打乱搜索的顺序,所以我们可以用queue来存储.

        基本模板为:

#include 
#include  
#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 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是个很有用的算法.

你可能感兴趣的:(广度优先搜索bfs)