惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

大猫的无限游戏
大猫的无限游戏
Webroot Blog
Webroot Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
T
Threat Research - Cisco Blogs
V2EX - 技术
V2EX - 技术
L
LINUX DO - 热门话题
Google DeepMind News
Google DeepMind News
Recorded Future
Recorded Future
S
Schneier on Security
I
InfoQ
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
The GitHub Blog
The GitHub Blog
S
Security @ Cisco Blogs
O
OpenAI News
W
WeLiveSecurity
Vercel News
Vercel News
阮一峰的网络日志
阮一峰的网络日志
Simon Willison's Weblog
Simon Willison's Weblog
人人都是产品经理
人人都是产品经理
Cloudbric
Cloudbric
The Last Watchdog
The Last Watchdog
The Hacker News
The Hacker News
Google Online Security Blog
Google Online Security Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
GbyAI
GbyAI
NISL@THU
NISL@THU
T
Tailwind CSS Blog
V
Visual Studio Blog
PCI Perspectives
PCI Perspectives
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Jina AI
Jina AI
D
DataBreaches.Net
B
Blog RSS Feed
N
News and Events Feed by Topic
N
News and Events Feed by Topic
H
Heimdal Security Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
腾讯CDC
Latest news
Latest news
V
Vulnerabilities – Threatpost
Hacker News: Ask HN
Hacker News: Ask HN
WordPress大学
WordPress大学
V
V2EX
aimingoo的专栏
aimingoo的专栏
博客园 - 司徒正美
Apple Machine Learning Research
Apple Machine Learning Research
D
Darknet – Hacking Tools, Hacker News & Cyber Security
The Register - Security
The Register - Security
Help Net Security
Help Net Security

faryou的博客

出租车上的对话 faryou的博客-告别小高一 faryou的博客-中考 · 竞赛 · 生活 · 思考 5月月考 - faryou的博客 - 日记 faryou的博客-五一回老家 【汇编 - 功能】中断安装中断实现 【汇编&硬件】时钟中断的具体实现 faryou的博客-这些年,我不再看《熊出没》 【汇编&硬件】关机中断的具体实现 【汇编&硬件】网络连接相关中断的具体实现 faryou的博客-年初小记 【汇编&硬件】鼠标控制中断的具体实现 【汇编&硬件】声音输出中断的具体实现 【汇编&硬件】屏幕输出中断的具体实现 【汇编&硬件】磁盘读取中断的具体实现 【汇编&硬件】键盘读取中断的具体实现 【汇编】汇编环境的搭建及Debug的使用教程 【汇编】漫谈:学习汇编后的一些思考 faryou的博客-关于本站即日起实行“一站三体”运营制度 【汇编基础教程】完结篇 写在最后:前言 【汇编基础教程】使用BIOS的中断实现键盘输入及磁盘I/O 【汇编基础教程】中断 【汇编基础教程】端口 【汇编基础教程】标志寄存器 【汇编基础教程】再谈栈 【汇编基础教程】段 【汇编基础教程】来存一些数据! 【汇编基础教程】寄存器和内存&一些基本命令的说明 【汇编基础教程】来写个“函数” 【汇编基础教程】更灵活的定位内存 【汇编基础教程】理解一下[bx]和loop指令 【汇编基础教程】跳一跳! faryou的博客-我的竞赛经历&对人生的一些思考 faryou的博客-关于现在中小学计算机课的一些想法及思考 faryou的博客-2025年度总结 faryou的博客-临平山下十五年 faryou的博客-Windows 10即将停止支持,谈谈自己从小到大用电脑的感受 faryou的博客-谈谈一名10后的怀旧情怀 【汇编基础教程】8086CPU工作原理 【C语言】指针的理解与应用 【算法教程】【C/C++】DP(动态规划):区间DP——程序设计思路与代码实现 【算法教程】【C/C++】DFS(深度优先搜索)——程序设计思路与代码实现 【算法教程】【C/C++】单源最短路径——程序设计思路与代码实现 【算法教程】【C/C++】最小生成树——程序设计思路与代码实现 【算法教程】【C/C++】并查集——程序设计思路与代码实现 【算法教程】【C/C++】DP(动态规划):背包DP——程序设计思路与代码实现 【算法教程】【C/C++】DP(动态规划):简单动规问题——程序设计思路与代码实现 【算法教程】【C/C++】递推——程序设计思路与代码实现 【算法教程】【C/C++】三分算法——程序设计思路与代码实现 【算法教程】【C/C++】二分答案——程序设计思路与代码实现 【算法教程】【C/C++】二分查找——程序设计思路与代码实现 【算法教程】【C/C++】贪心算法——程序设计思路与代码实现 【算法教程】【C/C++】基础数学:快排——程序设计思路与代码实现 【算法教程】【C/C++】基础数学:快速幂——程序设计思路与代码实现 【算法教程】【C/C++】基础数学:进制转换——程序设计思路与代码实现 一文弄懂C++中的自定义函数 faryou的博客-2024年度总结
【算法教程】【C/C++】BFS(广度优先搜索)——程序设计思路与代码实现
作者: faryou · 2025-02-01 · via faryou的博客

前言
广度优先搜索适合用于解决一些走迷宫之类的问题,可以解决深度优先搜索“搜得太深一时出不来”的问题。今天我们学习一下BFS的基本思路。

程序设计思路
BFS与DFS不同就在于BFS是按照层次遍历(在树上表现为从上到下一层一层,横向遍历),而DFS则是有多深走多深,不管层数。理论上来说,两者都属于暴力。
BFS通过队列实现,即每次从队列中取出一个点进行相关操作,并在这次循环内察看其子节点是不是叶子节点,如果是非叶子节点就把这个点入队,之后将这个父节点出队,处理下一个点,直到处理完所有节点(队列空),实现遍历。
还是下面这棵树:
202408311725079771374628.png
使用BFS的遍历顺序为:2→7→8→1→6→9→5→3→4。

代码实现
来看一道题:
202408311725083121921990.png
这是一道经典的BFS题目,我们可以将马不同的行走路线看成一棵树上不同的分支。直接上代码——

#include <bits/stdc++.h>
using namespace std;

int n,m,x,y,ans[401][401],ssb[9]={0,-2,-2,-1,-1,2,2,1,1},sbb[9]={0,-1,1,-2,2,-1,1,-2,2},iq,aq;//n、m、x、y如题意,ans存放从起点到各个点的最短路径,iq、aq为临时变量
bool visit[401][401];//记录当前点有没有访问过

int main(){
    queue<int> f1,f2;//队列,分别记录f1与f2
    scanf("%d%d%d%d",&n,&m,&x,&y);
    for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) ans[i][j]=-1;
    f1.push(x);
    f2.push(y);//先将起点入队,开始计算
    ans[x][y]=0;//起点到起点距离为0
    for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) visit[i][j]=false;//初始化
    visit[x][y]=true;//已经访问过起点
    while(!f1.empty()){//循环直到队列空
        iq=f1.front();
        aq=f2.front();//取出x、y分别计算
        f1.pop();
        f2.pop();//出队
        for(int i=1;i<=8;i++){//马下一步可以到八个方向
            int nexx=iq+ssb[i];
            int nexy=aq+sbb[i];//临时变量记录
            if(nexx>0 && nexy>0 && nexx<=n && nexy<=m && !visit[nexx][nexy]){//判断是否超界或访问过
                visit[nexx][nexy]=true;//当前点标记
                ans[nexx][nexy]=ans[iq][aq]+1;
                f1.push(nexx);
                f2.push(nexy);//进队列
            }
        }
    }
    for(int i=1;i<=n;i++){//输出
        for(int j=1;j<=m;j++) printf("%-5d",ans[i][j]);
        printf("\n");
    }
    return 0;
}

再来看下面这题:
202408311725083785844735.png
这题可以视作遍历二叉树,即上楼和下楼分别为节点。看代码:

#include <bits/stdc++.h>
using namespace std;

struct node{//floor存放一层,d存放到该层的步数
    int floor,d;
}now;

int n,a,b,k[201],dist;//n、a、b、k如题意,dist为临时变量
bool vis[201];//记录是否到达
queue<node> iq;//队列

int main(){
    scanf("%d%d%d",&n,&a,&b);
    for(int i=1;i<=n;i++){
        scanf("%d",&k[i]);
        vis[i]=false;
    }//初始化+读入
    iq.push((node){a,0});//起点入队
    vis[a]=true;//起点已访问过
    while(!iq.empty()){//循环直到队列空
        now=iq.front();//存放这次循环要处理的点
        iq.pop();//出队
        if(now.floor==b) break;//当已经到达终点时,退出循环。由于广搜可以保证搜索的步数逐渐增加,所以不会漏掉步数更少的情况
        dist=now.floor-k[now.floor];//临时记录(下楼)
        if(dist>=1 && dist<=n && !vis[dist]){//判断未超界且未访问过
            iq.push((node{dist,now.d+1}));//入队
            vis[dist]=1;//标记
        }
        dist=now.floor+k[now.floor];//临时记录(上楼)
        if(dist>=1 && dist<=n && !vis[dist]){//同上
            iq.push((node{dist,now.d+1}));
            vis[dist]=1;
        }
    }
    if(now.floor==b) printf("%d",now.d);
    else printf("-1");
    return 0;
}

这里注意不要忘记开vis数组,否则可能会死循环(出现环状结构时)。

结语
BFS是很重要的一个算法,只要想清楚自己的树是怎么样的就可以轻松完成程序。我是faryou,再见!