BFS专题4 迷宫最短路径(输出路径)


BFS专题4 迷宫最短路径(输出路径)

原创 已于 2023-08-30 21:33:01 修改 · 粉丝可见 · 651 阅读 · 2 · 5 · 本内容遵循CC 4.0 BY-SA版权协议 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 · 编辑
文章链接:https://blog.csdn.net/hacker_51/article/details/132570442

题目:

样例:

cpp<br/>3 3<br/>0 1 0<br/>0 0 0<br/>0 1 0<br/>
cpp<br/>1 1<br/>2 1<br/>2 2<br/>2 3<br/>3 3<br/>

思路:

这里刚开始看的时候会可能有点复杂了,因为是递归。

但是只要理解了含义,脑袋里模拟一下还是可以理解的。首先还是 之前那样BFS常规搜索

只是这里不用输出步数了,所以我们可以省略一层循环,直接搜索求路径。

求路径的方法核心思想就是 记录每个点是由哪上一个点所得来的。

然后记录完全部的点所对应的上一个点后,从终点递归一遍到起点,然后输出路径即可。

代码详解如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include <iostream>
#include <queue>
#include <cstring>
#define endl '\n'
#define x first
#define y second
#define mk make_pair
#pragma GCC optimize(3,"Ofast","inline")
#define ___G std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
using namespace std;
const int N = 300;

using PII = pair<int, int>;

// 控制走动方向
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

int n, m; // 迷宫大小
int r[N][N]; // 记录走动过的地方
int g[N][N]; // 迷宫地图

PII pre[N][N]; // 记录路径

// 走动下一个坐标条件
inline bool isRun(int x, int y)
{
return (x >= 0 && x < n && y >= 0 && y < m && !r[x][y] && !g[x][y]);
}


inline bool BFS(int x, int y)
{
// 存储坐标
queue<PII>q;
// 存储起点
q.push(mk(x, y));

// 开始广度搜索
while (q.size())
{
auto now = q.front();
q.pop();

if (now.x == n - 1 && now.y == m - 1)
{
// 如果已经走动到了右下角的出口
// 结束搜索
return false;
}

// 标记已经走动过了当前的地点
r[now.x][now.y] = true;

// 枚举四个方向能否走动
for (int i = 0; i < 4; ++i)
{
// 取出该方向的坐标
int bx = now.x + dx[i];
int by = now.y + dy[i];

// 判断是否满足走动条件
if (isRun(bx, by))
{
// 存储下一次走动的坐标
q.push(mk(bx, by));

// 标记下一次会走动的坐标
r[bx][by] = true;

// 记录路径
// 下一个点是 由 哪上一个最优的点得到的
// 然后 反过来递归回去找 就得到 起点到终点的路径了
pre[bx][by] = mk(now.x, now.y);
}
}
}
// 如果不能走到终点输出结果
return true;
}

inline void Print_path(PII now)
{
// 取出当前 now 对应的上一个的坐标
auto previous = pre[now.x][now.y];

// 如果递归到达了边界,说明已经到达了起点
// 开始输出路径
if (previous == PII(-1, -1))
{
cout << now.x + 1 << ' ' << now.y + 1 << endl;
return ;
}

// 继续递归往回找路径
Print_path(previous);

cout << now.x + 1 << ' ' << now.y + 1 << endl;
return ;
}
inline void solve()
{
// 这里是初始化路径全部为 -1,-1,作为递归边界
memset(pre, -1, sizeof pre);

cin >> n >> m;
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < m; ++j)
{
cin >> g[i][j];
}
}
if (BFS(0, 0))
{
puts("-1");
}
else
{
// 打印路径
// 由于是从后面开始记录上一个路径点
// 所以我们应该从终点开始递归查找路径
Print_path(mk(n - 1, m - 1));
}
}


int main()
{
// freopen("a.txt", "r", stdin);
___G;
int _t = 1;
// cin >> _t;
while (_t--)
{
solve();
}

return 0;
}

最后提交:


觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭

微信二维码

wechat pay

支付宝二维码

ali pay

BFS专题4 迷宫最短路径(输出路径)
http://blog.angindem.cn/2023/08/30/Angindem-CSDN博客/042_42/
作者
Angindem
发布于
2023年8月30日
许可协议