• 搜索——最短路模型,多源bfs


            最短路模型,即求从起点到终点的最短路径,我们可以选择dijkstra,spfa等等,在这里我们可以利用宽搜(bfs)的特性来求,因为bfs是一层一层的向外扩展的,所以当我们第一次遍历到终点时,所在的层数即为起点到终点的最短路径。

            多源bfs,顾名思义,多个起点的bfs,与一般的bfs不同的地方在于根据题目要求,将多个起点在初始时全部加入队列即可,后续遍历和普通bfs没什么不同。

    1076. 迷宫问题 - AcWing题库

    给定一个 n×n 的二维数组,如下所示:

    1. int maze[5][5] = {
    2. 0, 1, 0, 0, 0,
    3. 0, 1, 0, 1, 0,
    4. 0, 0, 0, 0, 0,
    5. 0, 1, 1, 1, 0,
    6. 0, 0, 0, 1, 0,
    7. };

    它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。

    数据保证至少存在一条从左上角走到右下角的路径。

    输入格式

    第一行包含整数 n。

    接下来 n 行,每行包含 n 个整数 0 或 1,表示迷宫。

    输出格式

    输出从左上角到右下角的最短路线,如果答案不唯一,输出任意一条路径均可。

    按顺序,每行输出一个路径中经过的单元格的坐标,左上角坐标为 (0,0)(0,0),右下角坐标为 (n−1,n−1)。

    数据范围

    0≤n≤1000

    输入样例:
    1. 5
    2. 0 1 0 0 0
    3. 0 1 0 1 0
    4. 0 0 0 0 0
    5. 0 1 1 1 0
    6. 0 0 0 1 0
    输出样例:
    1. 0 0
    2. 1 0
    3. 2 0
    4. 2 1
    5. 2 2
    6. 2 3
    7. 2 4
    8. 3 4
    9. 4 4

    思路:简单bfs,要求输出路径,为了方便记录路径,我们从终点出发到起点,开辟一个二维数组记录一下每个点的前驱点即可

    1. #include
    2. #include
    3. #include
    4. #define x first
    5. #define y second
    6. using namespace std;
    7. typedef pair<int, int> PII;
    8. const int N = 1010;
    9. int n;
    10. int g[N][N];
    11. PII q[N * N];
    12. PII pre[N][N];//每个点的上一步
    13. int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};
    14. void bfs(int sx, int sy)
    15. {
    16. int hh = -1, tt = -1;
    17. q[ ++ tt ] = {sx, sy};
    18. memset(pre, -1, sizeof pre);
    19. pre[sx][sy] = {0, 0};
    20. while (hh <= tt)
    21. {
    22. PII t = q[ ++ hh];
    23. for(int i = 0; i < 4; i ++ )
    24. {
    25. int a = t.x + dx[i], b = t.y + dy[i];
    26. if(a < 0 || a >= n || b < 0 || b >= n || g[a][b] || pre[a][b].x != -1) continue;
    27. q[ ++ tt] = {a, b};
    28. pre[a][b] = t;
    29. }
    30. }
    31. }
    32. int main()
    33. {
    34. cin >> n;
    35. for(int i = 0; i < n; i ++ )
    36. for(int j = 0; j < n; j ++ )
    37. cin >> g[i][j];
    38. bfs(n - 1, n - 1);
    39. PII end = {0, 0};
    40. while (true)
    41. {
    42. printf("%d %d\n", end.x, end.y);
    43. if(end.x == n - 1 && end.y == n - 1) break;
    44. end = pre[end.x][end.y];
    45. }
    46. return 0;
    47. }

    173. 矩阵距离 - AcWing题库

    给定一个 N 行 M 列的 0101 矩阵 A,A[i][j] 与 A[k][l] 之间的曼哈顿距离定义为:

    dist(A[i][j],A[k][l])=|i−k|+|j−l|

    输出一个 N 行 M 列的整数矩阵 B,其中:

    B[i][j]=min1≤x≤N,1≤y≤M,A[x][y]=1dist(A[i][j],A[x][y])

    输入格式

    第一行两个整数 N,M。

    接下来一个 N 行 M 列的 0101 矩阵,数字之间没有空格。

    输出格式

    一个 N 行 M 列的矩阵 B,相邻两个整数之间用一个空格隔开。

    数据范围

    1≤N,M≤1000

    输入样例:
    1. 3 4
    2. 0001
    3. 0011
    4. 0110
    输出样例:
    1. 3 2 1 0
    2. 2 1 0 0
    3. 1 0 0 1

    思路:将多个起点一起加入队列然后和普通bfs一样宽搜即可

    1. #include
    2. #include
    3. #include
    4. #include
    5. #define x first
    6. #define y second
    7. using namespace std;
    8. typedef pair<int, int> PII;
    9. const int N = 1010;
    10. int n, m;
    11. char A[N][N];
    12. int B[N][N];
    13. void bfs()
    14. {
    15. int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
    16. memset(B, -1, sizeof B);
    17. queue q;
    18. for(int i = 0; i < n; i ++ )
    19. for(int j = 0; j < m; j ++ )
    20. if(A[i][j] == '1')
    21. {
    22. B[i][j] = 0;
    23. q.push({i, j});
    24. }
    25. while (q.size())
    26. {
    27. PII t = q.front();
    28. q.pop();
    29. for(int i = 0; i < 4; i ++ )
    30. {
    31. int a = t.x + dx[i], b = t.y + dy[i];
    32. if(a < 0 || a >= n || b < 0 || b >= m) continue;
    33. if(B[a][b] != -1) continue;
    34. B[a][b] = B[t.x][t.y] + 1;
    35. q.push({a, b});
    36. }
    37. }
    38. }
    39. int main()
    40. {
    41. cin >> n >> m;
    42. for(int i = 0; i < n; i ++ ) cin >> A[i];
    43. bfs();
    44. for(int i = 0; i < n; i ++ )
    45. {
    46. for(int j = 0; j < m; j ++ ) cout << B[i][j] << " ";
    47. puts("");
    48. }
    49. return 0;
    50. }

    188. 武士风度的牛 - AcWing题库

    1100. 抓住那头牛 - AcWing题库

  • 相关阅读:
    nginx升级版本
    2022 - 8 洛谷
    c++内存管理
    IO学习系列之使用文件IO的接口在一个目录下,实现Linux命令“ls -l”的功能
    力扣 1656. 设计有序流
    uniapp-ios打包安装测试
    C++ 多态
    java计算机毕业设计天津城建大学校友录管理系统源程序+mysql+系统+lw文档+远程调试
    嵌入式软硬分工与职业发展
    京东18A整理出最牛《Spring技术内幕》,深入解析Spring原理
  • 原文地址:https://blog.csdn.net/qq_62417282/article/details/133075990