广度优先搜索详解--BFS--蒟蒻的学习之路

 1.什么是广度优先搜索?

广度优先搜索(Breadth-First Search,简称BFS)是一种遍历或搜索树和图的算法,也称为宽度优先搜索,BFS算法从图的某个节点开始,依次对其所有相邻节点进行探索和遍历,然后再对这些相邻节点的相邻节点进行探索,直到遍历完所有的节点。

2.c++与c语言的实现的不同

c++ BFS算法使用队列来辅助实现,c语言往往通过数组来辅助实现(后面会有不同的样例来解释不同的语言的实现形式)c语言看起来可能有点啊难理解,需要通过模拟队列!

3.BFS的使用场景

一般来说广度优先搜索适用于解决两点之间的最短路径问题

广度优先搜索是从起点出发,以起点为中心,一圈一圈搜索的,一旦找到终点,记录之前走过的节点,这样就是一条最短路径

BFS常用于寻找最短路径,数据小的最短路径可以用DFS,大点的用DFS会超时,之前写过一道,这样子的题型

DFS/BFS算法在蓝桥杯竞赛中很常见。几乎每一年都会考到DFS/BFS算法!

4.BFS的使用步骤

将起始节点放入队列中,然后将起点标记为已经访问过,然后依次取出队列中的节点,访问其相邻节点,并将其加入队列。这样可以保证从起始节点出发,依次按照距离顺序遍历节点。因为它按照从起点到每个节点的距离来探索节点。

BFS算法通常使用队列来实现,BFS算法的具体步骤如下:

  1. 创建一个队列,将起始节点加入队列;
  2. 创建一个集合,用于存储已经访问过的节点;
  3. 从队列中取出一个节点,并将其标记为已访问;
  4. 访问该节点的所有相邻节点,如果相邻节点未被访问,则将其加入队列;
  5. 重复步骤3和步骤4,直到队列为空。

5.算法模板:

首先我们需要一个队列来辅助BFS实现,还需要一个初始化的输入数组,还有一个标记数组。先找到BFS的起点跟终点,确定好之后,先把起点vis==1,把起点入队,然后进入BFS函数,进入BFS函数一般先是一个大while循环,来管理队列的入队、出队。由于点都是二维的,我们一般都是用pair或者结构体来表示点,新建一个点来存储队头的信息,存完就可以让队头出队了。然后判断是否到达了目标结点,一个if判断,下面就是跟dfs一样,一个for循环遍历周围所有的点,不合法的直接continue掉,合法的标记完vis后入队,有的题目会有回溯,像在部分最短路搜索。

queue<node> q;
void bfs(){
    while(!q.empty()){
        node tmp=q.top();//node为(x,y)结构体
        q.pop();//出队
        if(到达目标终点){
            更新
            return;
        }
        //有的会有剪枝
        for(int i=0;i<m;i++){//m个方向
            int dx=tmp.x+bx[i];
            int dy=tmp.y+by[i];
            if(下标越界){
                continue;
            }
            if(已经被标记过了){
                continue;
            }
            //否则就是合法的
            vis[dx][dy]=1;//先标记
            q.push(node{dx,dy});//再新点入队
        }
    }
}

6.例题讲解 

P1135 奇怪的电梯 - 洛谷

 这里有一个需要注意的地方for输入的时候要记得从1开始因为上下娄底要用到这个准确的位置下标

#include<bits/stdc++.h>
using namespace std;
#define N 400
int a[N];//接收上下楼梯的值
int visu[N];//判断当前楼层是否被访问
int n, Start, End;
struct pos {//表示当前状态
    int level;//目前的当层楼层
    int step;//到当前楼层的步数
};
void bfs();
int main() {
    while (cin >> n) {
        if (n == 0)break;
        cin >> Start >> End;
        for (int i = 1; i <= n; i++) {
            visu[i] = 0;
            cin >> a[i];
        }
        bfs();
    }
    return 0;
}
void bfs() {
    pos cur, next;//定义两个变量
    cur.level = Start;//接受初始值的楼梯层数状态
    cur.step = 0;
    queue<pos>qu;//队列qu变量
    qu.push(cur);//输入cur
    visu[Start] = 1;//表示当前楼层已经被访问
    while (!qu.empty()) {//如果队列不为空
        cur = qu.front();//cur接受首元素位置
        qu.pop();//弹出首元素位置
        if (cur.level == End) {//如果起点等于终点//打印当前步数(开始错在此处,因为写成start1==end,start1是没有变化的,所以不行)
            printf("%d", cur.step);
            return;
        }
        next.level = cur.level + a[cur.level];//向上走
        next.step = cur.step + 1;//步数加一
        if (next.level <= n) {
            if (visu[next.level] == 0) {
                visu[next.level] = 1;
                qu.push(next);
            }
        }
        next.level = cur.level - a[cur.level];
        next.step = cur.step + 1;
        if (next.level >= 1) {
            if (visu[next.level] == 0) {
                visu[next.level] = 1;
                qu.push(next);
            }
        }
    }
    cout << "-1" << endl;//最后实在没有找到返回-1
    return;
}

已补上c语言表现形式

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int n, start, next;
int a[1000], vis[1000];
struct pos {
	int h, step;
}q[1000];
void bfs() {
	int front = 1, rear = 1;
	q[rear].h = start;
	q[rear].step = 0;
	rear++;
	vis[start] = 1;
	while (front < rear) {
		struct pos cur, net;
		cur = q[front];
		front++;

		if (cur.h == next) {
			printf("%d", cur.step);
			return;
		}

		net.h = cur.h + a[cur.h];
		net.step = cur.step + 1;
		if (net.h <= n && net.h >= 1 && vis[net.h] == 0) {
			vis[net.h] = 1;
			q[rear] = net;
			rear++;
		}

		net.h = cur.h - a[cur.h];
		net.step = cur.step + 1;
		if (net.h <= n && net.h >= 1 && vis[net.h] == 0) {
			vis[net.h] = 1;
			q[rear] = net;
			rear++;
		}
	}
	printf("-1");
	return;
}
int main() {
	scanf("%d%d%d", &n, &start, &next);
	for (int i = 1; i <= n; i++)scanf("%d", &a[i]);
	bfs();
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/972869.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

. Unable to find a @SpringBootConfiguration(默认软件包中的 Spring Boot 应用程序)

解决&#xff1a; 新建一个包即可 问题&#xff1a; 默认软件包中的 Spring Boot 应用程序。 原因&#xff1a; 默认包的定义 &#xff1a; 如果一个 Java 类没有使用 package 声明包名&#xff0c;则该类会被放置在默认包中。Spring Boot 遵循 Java 的包管理约定&#xff…

DeepSeek企业级部署实战指南:从服务器选型到Dify私有化落地

对于个人开发者或尝鲜者而言&#xff0c;本地想要部署 DeepSeek 有很多种方案&#xff0c;但是一旦涉及到企业级部署&#xff0c;则步骤将会繁琐很多。 比如我们的第一步就需要先根据实际业务场景评估出我们到底需要部署什么规格的模型&#xff0c;以及我们所要部署的模型&…

“三次握手”与“四次挥手”:TCP传输控制协议连接过程

目录 什么是TCP协议 “三次握手”建立连接 “四次挥手”断开连接 “三次握手”和“四次挥手”的反思 总结 什么是TCP协议 想象一下&#xff0c;你和远方的朋友要进行一场电话交流&#xff0c;但这通电话不仅仅是随便聊聊&#xff0c;而是要传递一封重要的信件。为了确保这…

网络运维学习笔记 012网工初级(HCIA-Datacom与CCNA-EI)某机构新增:GRE隧道与EBGP实施

文章目录 GRE隧道&#xff08;通用路由封装&#xff0c;Generic Routing Encapsulation&#xff09;协议号47实验&#xff1a;思科&#xff1a;开始实施&#xff1a; 华为&#xff1a;开始实施&#xff1a; eBGP实施思科&#xff1a;华为&#xff1a; GRE隧道&#xff08;通用路…

Android 动态加入Activity 时 manifest 注册报错解决。使用manifestPlaceholders 占位

需求如下&#xff1a; 项目 测试demo 有多个渠道&#xff0c;部分渠道包含支付功能&#xff0c;在主测试代码外&#xff0c;需要一个单独 Activity 调用测试代码。 MainActivityPayActivity渠道A包含不包含渠道B包含包含 因为支付功能需要引入对应的 moudule&#xff0c;因此…

【koa】05-koa+mysql实现数据库集成:连接和增删改查

前言 前面我们已经介绍了第二阶段的第1-4点内容&#xff0c;本篇介绍第5点内容&#xff1a;数据库集成&#xff08;koamysql&#xff09; 也是第二阶段内容的完结。 一、学习目标 在koa项目中正常连接数据库&#xff0c;对数据表进行增删改查的操作。 二、操作步骤 本篇文章…

linux--关于makefile

makefile文件 可以指定编译顺序&#xff0c;这样方便一个项目的多个文件要编译的挨个操作的麻烦。 makefile文件的命名&#xff1a;makefile 或者 Makefile 必须是这俩&#xff0c;系统才能识别 规则的书写语法如下&#xff1a; 一个makefile内可以有多个规则 目标:依赖a 依…

俄罗斯方块游戏完整代码示例

以下是一个基于Cocos Creator引擎开发的俄罗斯方块游戏的完整代码示例。该游戏实现了俄罗斯方块的基本功能&#xff0c;并且代码整合在单个文件中&#xff0c;无需任何外部依赖&#xff0c;可以直接在浏览器中运行。 1. 创建Cocos Creator项目 首先&#xff0c;确保你已经安装了…

学习kafka和flink

kafka kafka安装一套流程 方法一&#xff1a;启动需安装zookeeper和kafka 【Kafka】Windows下安装Kafka&#xff08;图文记录详细步骤&#xff09; 安装Tzq2018写的上面链接安装的&#xff0c;一切很顺利&#xff0c;除了zookeeper的环境变量不管如何配置都不管用&#xff0…

SLT-加载表添加字段重新刷数

1、LTRC数据提供->输入表名->停止加载/复制 2、LTRS添加表字段&#xff08;只有在加载部分字段的情况下&#xff09;&#xff1b; 在查看修改概览页将需要的字段选中并删除&#xff0c;删除的字段自动归集到已修改概览里。 3、数据提供-》输入表名-》创建/数据库视图&am…

【黑马点评优化】2-Canel实现多级缓存(Redis+Caffeine)同步

【黑马点评优化】2-Canel实现多级缓存&#xff08;RedisCaffeine&#xff09;同步 0 背景1 配置MySQL1.1 开启MySQL的binlog功能1.1.1 找到mysql配置文件my.ini的位置1.1.2 开启binlog 1.2 创建canal用户 2 下载配置canal2.1 canal 1.1.5下载2.2 配置canal2.3 启动canal2.4 测试…

【iOS】SwiftUI状态管理

State ObservedObject StateObject 的使用 import SwiftUIclass CountModel: ObservableObject {Published var count: Int 0 // 通过 Published 标记的变量会触发视图更新init() {print("TimerModel initialized at \(count)")} }struct ContentView: View {State…

组合总和力扣--39

目录 题目 思路 剪枝优化 代码 题目 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的…

基于知识图谱的问答系统:后端Python+Flask,数据库Neo4j,前端Vue3(提供源码)

基于知识图谱的问答系统&#xff1a;后端PythonFlask&#xff0c;数据库Neo4j&#xff0c;前端Vue3 引言 随着人工智能技术的不断发展&#xff0c;知识图谱作为一种结构化的知识表示方式&#xff0c;逐渐成为问答系统的重要组成部分。本文将介绍如何构建一个基于知识图谱的问答…

【第四届网络安全、人工智能与数字经济国际学术会议(CSAIDE 2025】网络安全,人工智能,数字经济的研究

重要信息 会议官网&#xff1a;www.csaide.net 会议时间&#xff1a;2025年3月7-9日 会议地点&#xff1a;马来西亚-马来西亚理工大学新山校区&#xff08;线上线下混合&#xff09; 简介 过去几年&#xff0c;数字经济蓬勃发展&#xff0c;已成为全球经济增长的驱动力。…

VSCode AI提效工具,通义灵码前端开发体验

安装 安装依旧很简单&#xff0c;vs code拓展插件中搜索就出来了&#xff0c;记住下边这个图标。 亮点 新接入了deepseek-v3\deepseek-r1模型&#xff0c;不仅支持智能问答&#xff0c;而且增加了AI程序员&#xff0c;可以直接按照完成编码任务&#xff0c;修改优化代码&am…

Ansys Zemax | 使用衍射光学器件模拟增强现实 (AR) 系统的出瞳扩展器 (EPE):第 2 部分

附件下载 联系工作人员获取附件 在 OpticStudio 中使用 RCWA 工具为增强现实&#xff08;AR&#xff09;系统设置出瞳扩展器&#xff08;EPE&#xff09;的示例中&#xff0c;首先解释了 k空间中光栅的规划&#xff0c;并详细讨论了设置每个光栅的步骤。 介绍 本文提供了多…

深度学习04 数据增强、调整学习率

目录 数据增强 常用的数据增强方法 调整学习率 学习率 调整学习率 ​调整学习率的方法 有序调整 等间隔调整 多间隔调整 指数衰减 余弦退火 ​自适应调整 自定义调整 数据增强 数据增强是通过对训练数据进行各种变换&#xff08;如旋转、翻转、裁剪等&#xff09;&am…

微软宣布 Windows 11 将不再免费升级:升级需趁早

大家都知道如果你现在是Windows 10 系统&#xff0c;其实可以免费升级到正版 Windows 11&#xff0c;只要你的电脑配置满足 TPM2.0要求。 而最近微软已经公布了 Windows 10 的最后支持时间&#xff0c;也就是今年10月14日&#xff0c;在这之后微软将不再对Windows 10负责&#…

【Spring详解三】默认标签的解析

三、默认标签的解析 Spring的标签中有 默认标签和 自定义标签&#xff0c;两者的解析有着很大的不同&#xff0c;这次重点说默认标签的解析过程。 DefaultBeanDefinitionDocumentReader.class 默认标签的解析是在 DefaultBeanDefinitionDocumentReader.parseDefaultElement()函…