迷宫问题BFS和DFS(模板)
DFS的基本结构:
void dfs(int 参数1, int 参数2)
{
if (不满足要求)
return; //剪枝条件
if (达到目标值) {
存储当前答案;
return;
}
dfs(下一步);
}
模板代码如下:
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
/*
迷宫问题的广度优先搜索和深度优先搜索
.表示路,#表示墙
起点[0,0],终点[n-1][m-1]
*/
struct node {
int x; //纵轴坐标
int y; //横轴坐标
};
int dx[4] = {0, 1, 0, -1}; //纵坐标的变化
int dy[4] = {1, 0, -1, 0}; //横坐标的变化
int n, m; //行数,列数
char maze[25][25]; //存储迷宫的数组
bool vis[25][25]; //标记数组
int dir[25][25]; //距离数组
void bfs(node start) //广度优先搜索
{
node normal, temp;
int xx, yy;
queue<node> q; //定义一个保存坐标的队列
while (!q.empty())
q.pop(); //清空队列
q.push(start); //存入开始坐标
dir[start.x][start.y] = 0; //标记此点的步数为0
while (!q.empty()) //循环条件是队列不为空
{
normal = q.front(); //取出队列中的坐标
q.pop(); //删除坐标
vis[normal.x][normal.y] = true; //标记此坐标已经走过
for (int i = 0; i < 4; i++) //循环遍历四个方向
{
xx = normal.x + dx[i];
yy = normal.y + dy[i];
if (xx >= 0 && xx < n && yy >= 0 && yy < m && maze[xx][yy] == '.' &&
!vis[xx][yy]) { //坐标不超出坐标系范围,并且是路不是墙,而且从来没有走过
temp.x = xx;
temp.y = yy;
q.push(temp); //加入队列
dir[xx][yy] = dir[normal.x][normal.y] + 1; //走到此点是前一点的步数加一
}
}
}
}
void dfs(int xx, int yy, int step) //深度优先搜索
{
int nx, ny;
if (x == n - 1 && y == m - 1) {
cout << step << endl;
return;
} else {
for (int i = 0; i < 4; i++) {
nx = x + dx[i];
ny = y + dy[i];
if (nx >= 0 && nx < n && ny >= 0 && ny < m && maze[nx][ny] == '.' && !vis[nx][ny]) {
vis[nx][ny] = true;
dfs(nx, ny, step + 1);
vis[nx][ny] = false;
}
}
}
}
int main()
{
node start;
while (cin >> n >> m) // n代表列数,m代表行数
{
if (n == 0 && m == 0)
break;
memset(dir, 0, sizeof(dir)); //初始化步数数组
memset(vis, false, sizeof(vis)); //初始化轨迹数组
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++) {
cin >> maze[i][j]; //输入迷宫
}
start.x = 0;
start.y = 0; //设置起点
memset(vis, false, sizeof(vis)); //初始化轨迹数组
bfs(start); //开始广搜
if (dir[n - 1][m - 1] == 0)
cout << "no way!" << endl; //无法到达
else
cout << "need " << dir[n - 1][m - 1] << " steps" << endl; //可以到达,输出步数
memset(vis, false, sizeof(vis)); //初始化轨迹数组
dfs(0, 0, 0);
}
return 0;
}
/*
3 3
..#
#.#
#..
5 5
.....
###.#
..#..
###..
...#.
*/