宽度优先搜索(BFS)总结

2023-11-13

基本思想

宽度优先搜索一般用队列(queue)实现,且总是按层次的顺序进行遍历。解这类题的一般套路:

  1. 定义一个结构体作为节点来存储信息(如保存横纵坐标x、y),后续队列以该结构体为单位来存储。
  2. 定义bool型数组,标记每个位置是否入过队列
  3. 定义增量数组表示若干个方向(四个、六个或八个)。
  4. 定义返回值为bool类型的检查函数,判断当前节点是否越界或入过队列或不满足题目条件。
  5. 编写宽搜函数bfs(),其中定义一个队列,将初始节点入队并标记已访问。当队列不为空一直循环,循环体中先访问队头元素并出队,检查其若干个方向上的节点是否满足条件,满足则入队并标记,继续循环。

代码模板

在这里插入图片描述

典型例题

在这里插入图片描述
在这里插入图片描述
输入:

5 5
.....
.*.*.
.*S*.
.***.
...T*
2 2

输出:

11

题解

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <queue>

using namespace std;

//记录每个节点的信息
struct node {
    int x;
    int y;
    int step;
} Node, T;

int n, m;
char map[100][100];
bool hasIn[100][100] = {false};		//标记是否已入过队列

//增量数组 四个方向 上下左右
int X[] = {0, 0, -1, 1};
int Y[] = {1, -1, 0, 0};

//判断是否越界或已入过队列
bool check(int x, int y)
{
    if(x < 0 || y < 0 || x >= m || y >= n)
        return false;
    if(map[x][y] == '*' || hasIn[x][y] == true)
        return false;
    return true;
}

int bfs(int x, int y)
{
    queue<node> q;
    //先将当前起始位置入队
    Node.x = x;
    Node.y = y;
    Node.step = 0;
    q.push(Node);
    hasIn[x][y] = true;
    //当队列不为空则一直循环
    while(!q.empty())
    {
    	//访问队首元素并出队
        node top = q.front();
        q.pop();
        //入过到终点则返回 必然是最少步数
        if(map[top.x][top.y] == 'T')        //top.x == T.x && top.y == T.y
            return top.step;
        //遍历四个方向
        for (int i = 0; i < 4; i ++ )
        {
            int newX = top.x + X[i];
            int newY = top.y + Y[i];
            //满足条件则入队
            if(check(newX, newY))
            {
                Node.x = newX;
                Node.y = newY;
                Node.step = top.step + 1;
                q.push(Node);
                hasIn[newX][newY] = true;		//标记
            }
        }
            
    }
    
    return -1;
}

int main()
{
    int x, y;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i ++ )
    {
        getchar();			//过滤换行符
        for (int j = 0; j < m; j ++ )
        {
        	//map[i][j] = getchar();
            scanf("%c", &map[i][j]);              //[segmentation fault] scanf字符要加&
        }
        map[i][m + 1] = '\0';
    }
    
    scanf("%d%d", &x, &y);
    printf("%d\n", bfs(x, y));
    return 0;
}

总结

bfs主要就是应用一个队列和增量数组,将队列中队头元素能到达的每一个节点依次进行遍历,满足条件则入队,直到队空为止。此类思想适合解决迷宫、地图类问题,就是优先遍历当前节点能直接到达的节点。具体问题还需在模板上做特定修改,要灵活运用。

此类题目汇总(持续更新)

  1. 【蓝桥杯java】迷宫(BFS)
  2. PAT A1091 Acute Stroke(三维数组BFS)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

宽度优先搜索(BFS)总结 的相关文章

随机推荐

  • java如何根据模板填充数据生成word文档

    java根据模板填充数据生成word文档 这篇文章干什么 思路总览 1 准备word模板 2 转换文件格式 3 编写代码 补充 下载流 这篇文章干什么 使用代码将word模板内容进行替换 并输出替换后的word 思路总览 1 准备一个wor
  • 计算机很多文件无法删除,电脑有文件删不掉怎么办?电脑有文件删不掉解决方法介绍...

    电脑是我们日常生活中经常使用的一种电子产品 有了电脑之后 我们的生活方式也因此而改变了许多 大多数人都是以电脑作为娱乐产品 电脑让我们在工作学习时资源共享也更方便了一些 效率得到了很大提高 但是作为 高科 技产品 很多人对电脑的使用其实并不
  • 【MATLAB编程学习】自己实现矩阵乘法

    MATLAB编程学习 自己实现矩阵乘法 欢迎关注 高强度更新和MATLAB PYTHON编程 C 编程 算法编程 深度学习 自然语言处理 图像处理 OPENCV等相关知识 这是也给简单的课后题 不过可以帮助我们更好的理解矩阵乘法以及matl
  • 反卷积通俗详细解析与nn.ConvTranspose2d重要参数解释

    文章目录 反卷积的作用 卷积中padding的几个概念 No Padding Half Same Padding Full Padding 反卷积 反卷积中的Padding参数 反卷积的stride参数 反卷积的output padding
  • 0、1编码

    一 声音的0 1编码 1 声音数据的编码过程 声音是一种连续的波 要把连续的波用0 1进行编码 需要经过采样 量化两步完成 1 采样就是每隔一定的时间 测取连续波上的一个振幅值 2 量化就是用一个二进制尺子计量采样得到的每个脉冲 假设有图1
  • openwrt之initramfs-kernel

    在下载openwrt系统时 经常能看到initramfs kernel bin squashfs factory bin squashfs sysupgrade bin等结尾的文件 factory适用于从原厂系统刷到openwrt sysu
  • The “path“ argument must be of type string. Received undefined; at(Object.extname)

    validateString下一行是 Object extname path js 752 5 的报错 原因是在nuxt config js中 把plugins的参数写错了 此处省略大量代码 const baseConfig require
  • Activiti 流程启动及节点流转源码分析

    作者 jiankunking 出处 http blog csdn net jiankunking 本文主要是以activiti study中的xiaomage xml流程图为例进行跟踪分析 具体的流程图如下 流程图对应的XML文件如下
  • unity 绘制属性雷达图 - 绘制描边(更改uv)

    实现的效果 先绘制一个五边形的mesh 然后在给边缘绘制一圈mesh 对uv进行重新赋值 实现描边效果 第一步 绘制mesh 绘制多边形mesh 首先先绘制一个五边形 mesh绘制要素 顶点 三角形 uv信息 顶点信息 就是勾勒三角形用的几
  • nginx静态代理设置二:静态文件在别的服务器

    动静结合 把网络上的路径映射成自己的虚拟机 修改共享的文件夹 映射的虚拟机也会同步更新 映射别的电脑的文件夹的时候要关闭防火墙 否则会一直连不上 1 新建静态文件夹StaticProxy 然后共享 选择账户Everyone就可以 2 本机测
  • void指针(void *)是什么?

    void 指针的使用规则 1 void 指针可以指向任意类型的数据 就是说可以用任意类型的指针对 void 指针赋值 例如 int a void p p a 如果要将 void 指针 p 赋给其他类型的指针 则需要强制类型转换 就本例而言
  • yii2学习笔记 --- 基础版配置链接多个数据库

    打开 config db php return class gt yii db Connection dsn gt mysql host localhost dbname yii2basic username gt root passwor
  • Qt数据库总结

    include
  • GD32F103配置PA15 PB3 PB4为普通IO

    PB3 PB4 PA15 作为普通IO时候 需要disable JTAG 释放出来 gpio pin remap config GPIO SWJ SWDPENABLE REMAP ENABLE 这个语句很重要 Function Key Sc
  • vue使用dhtmlx-gantt

    根据需求制作甘特图 绘制两时间段 相交地方为深颜色 没找到可以直接用的插件 于是就靠自己手动计算时间差与时间比例 但所得结果有部分误差 有更好组件欢迎交流 安装 npm install dhtmlx gantt save index js
  • Mysql数据库,查询结果为空值,如何处理?

    当sql查出空值的时候 如果想要获取 其中的值可能会出错 a res getString 字段 如果该字段的值是null 就会报错 所以需要在取字段值的时候做try catch 处理 try a res getString 字段 catch
  • unityShader物体表面流光效果

    本文转载自http blog csdn net lyh916 article details 51831720 参考链接 http liweizhaolili blog 163 com blog static 162307442012726
  • C++的排序

    C 十大排序 1 快速排序 2 插入排序 3 选择排序 4 冒泡排序 5 归并排序 6 堆排序 7 计数排序 8 桶排序 9 基数排序 10 希尔排序 11 补充 稳定排序 排序前后两个相等的数的相对位置不变 归并排序 冒泡排序 插入排序
  • On java 8 笔记——第六章 初始化和清理

    有两个安全性问题 初始化和清理 利用构造器保证初始化 在 Java 中 类的设计者通过构造器保证每个对象的初始化 如果一个类有构造器 那么 Java 会在用户使用对象之前 即对象刚创建完成 自动调用对象的构造器方法 从而保证初始化 构造器名
  • 宽度优先搜索(BFS)总结

    基本思想 宽度优先搜索一般用队列 queue 实现 且总是按层次的顺序进行遍历 解这类题的一般套路 定义一个结构体作为节点来存储信息 如保存横纵坐标x y 后续队列以该结构体为单位来存储 定义bool型数组 标记每个位置是否入过队列 定义增