浅谈BFS模板思路(一)
哈喽!这里是一只派大鑫,不是派大星。本着基础不牢,地动山摇的学习态度,从基础的C语言语法讲到算法再到更高级的语法及框架的学习。更好地让同样热爱编程(或是应付期末考试 狗头.jpg)的大家能够在学习阶段找到好的方法、路线,让天下没有难学的程序(只有秃头的程序员 2333),学会程序和算法,走遍天下都不怕!
前言:
来讲一下广度优先搜索BFS对应的题目里的使用模板,以及详细的解题思路过程,并给出一道经典案例来进行补充说明,最后给出解题代码收尾,相信你读完之后一定会有收获的!
广搜模板:
广度优先搜索一般由队列实现,且总是按层次的顺序进行遍历,其基本写法如下(可作模板用):
void BFS(int s){queue<int> q;q.push(s);while(!q.empty()){取出队首元素top;访问队首元素top;将队首元素出队;将top的下一层结点中未曾入队的结点全部入队,并设置为已入队} }
模板解读:
下面是对该模板中每一个步骤的说明,请结合代码一起看:
①定义队列q,并将起点s入队。
②写一个while循环,循环条件是队列q非空。
③在while循环中,先取出队首元素top,然后访问它(访问可以是任何事情,例如将其输出)。访问完后将其出队。
④将top的下一层结点中未曾入队的结点入队,并标记它们的层号为now的层号+1,同时设置这些入队的结点已入过队。
⑤返回②继续循环。
举个栗子:
下面举一个例子,希望读者能从中学习BFS的思想是如何通过队列来实现的,并能尝试学习写出本例的代码。
给出一个m×n的矩阵,矩阵中的元素为0或1。称位置(x,y)与其上下左右四个位置:(x,y+1)、(x,y-1)、(x+1,y)、(x-1,y)是相邻的。如果矩阵中有若干个1是相邻的(不必两两相邻),那么称这些1构成了一个“块”。求给定的矩阵中“块”的个数。
0 1 1 1 0 0 10 0 1 0 0 0 00 0 0 0 1 0 00 0 0 1 1 1 01 1 1 0 1 0 01 1 1 1 0 0 0
例如上面的6×7的矩阵中,“块”的个数为4。
分析栗子:
对这个问题,求解的基本思想是:
枚举每一个位置的元素,如果为0,则跳过;
如果为1,则使用BFS查询与该位置相邻的4个位置(前提是不出界),
判断它们是狗为1(如果某个相邻的位置为1,则同样去查询与该位置相邻的4个位置,知道整个“1”块访问完毕)。
而为了防止走回头路,一般可以设置一个bool型数组inq(即in queue的简写)来记录每个位置是否在BFS中已入过队。
一个小技巧是: 对当前位置(x,y)来说,由于与其相邻的四个位置分别为(x,y+1)、(x,y-1)、(x+1,y)、(x-1,y),那么不妨设置下面这两个增量数组,来表示四个方向(竖着看即为四个方向)。
int x[] = {0,0,1,-1};
int y[] = {1,-1,0,0};
这样就可以使用for循环来枚举4个方向,以确定与当前坐标(nowX,nowY)相邻的4个位置,如下所示:
for(int i = 0; i < 4; i++){newX = nowX + x[i];newY = nowY + Y[i]; }
解题代码:
下面给出本例的代码,希望读者能仔细理解代码中BFS的写法,并在之后尝试自己独立重写(请读者也用DFS实现本题):
#include<stdio.h>
#include<iostream>
#include<queue>
using namespace std;const int maxn = 100;
struct node{int x,y; //位置(x,y))
}Node;int n,m; //矩阵的大小为n*m
int matrix[maxn][maxn]; //保存01矩阵
bool inq[maxn][maxn] = {false}; //记录位置(x,y)是否已入过队
int X[4] = {0,0,1,-1}; //增量数组
int Y[4] = {1,-1,0,0};bool judge(int x,int y){//越界返回falseif(x >= n || x < 0 || y >= m || y < 0) return false;//当前位置为0,或(x,y)已入过队,返回falseif(matrix[x][y] == 0 || inq[x][y] == true) return false;//以上都不是,则返回truereturn true;
}
//BFS函数访问位置(x,y)所在的块,将该块中所有“1”的inq都设置为true
void BFS(int x,int y){queue<node> q; //定义一个队列Node.x = x, Node.y = y; //当前结点的坐标为(x,y)q.push(Node); //将结点Node入队inq[x][y] = true;while(!q.empty()){node top = q.front(); //取出队首元素q.pop(); //队首元素出队for(int i = 0; i < 4; i++){ //循环4次,得到4个相邻位置int newX = top.x + X[i];int newY = top.y + Y[i];if(judge(newX,newY)){ //如果新位置(newX,newY)需要访问//设置Node的坐标为(newX,newY)Node.x = newX, Node.y = newY;q.push(Node); //将结点Node加入队列inq[newX][newY] = true; //设置位置(newX,newY)已入过队}}}
}
int main(){scanf("%d%d",&n,&m);for(int x = 0; x < n; x++){for(int y = 0; y < m; y++){scanf("%d",&matrix[x][y]);}}int ans = 0; //存放结果 最后的块数for(int x = 0; x < n; x++){for(int y = 0; y < m; y++){//如果元素为1,且未入过队if(matrix[x][y] == 1 && inq[x][y] == false){ans++; //块数+1BFS(x,y); //访问整个块,将该块所有“1”的inq都标记为true}}}printf("%d\n",ans);return 0;
}
至此,这篇文章就讲完了,如果你觉得对你有帮助,不妨三连点赞收藏加关注,学习知识不迷路
浅谈BFS模板思路(一)相关推荐
- laytpl语法_浅谈laytpl 模板空值显示null的解决方法及简单的js表达式
浅谈laytpl 模板空值显示null的解决方法及简单的js表达式 laytpl 模板语法 {{ d.field }} 输出一个普通字段,不转义html 官方的说明 但d.field 为空时会显示nu ...
- 借WS2812 PWM DMA驱动调试浅谈STM32调试思路
借WS2812 PWM DMA驱动调试浅谈STM32调试思路 接触STM32差不多有4年了,在学校参加比赛时也需要进行各种调试工作,团队的配合也需要个人具有领域内快速定位与解决BUG的能力,前些日 ...
- 分布式服务架构的设计方案下—通过业务场景浅谈分布式设计思路
文章目录 分布式业务场景分析 分布式系统提高承载量的基本手段 并发模型(多线程.异步) 缓存/缓冲 硬件故障 资源利用率优化 软件服务内容更新 数据统计 目录服务 消息队列服务(ActiveMQ.Ze ...
- (转)浅谈dedecms模板引擎工作原理及自定义标签
理解织梦模板引擎有什么意义?一方面可以更好地自定义标签.更多在于了解织梦系统,理解模板引擎是理解织梦工作原理的第一步.理解织梦会使我们写php代码时更顺手,同时能学习一些php代码的组织方式. 这似乎 ...
- 浅谈动态规划 ——by cbw
浅谈动态规划 基本思路 动态规划算法通常用于求解具有某种最优性质的问题.在这类问题中,可能 会有许多可行解.每一个解都对应于一个值,我们希望找到具有最优值的解. 动态规划算法与分治法类似,其基本思想也 ...
- php smarty 原理,php模板原理PHP模板引擎smarty模板原理浅谈
mvc是开发中的一个伟大的思想,使得开发代码有了更加清晰的层次,让代码分为了三层各施其职.无论是对代码的编写以及后期的阅读和维护,都提供了很大的便利. 我们在php开发中,视图层view是不允许有ph ...
- 浅谈 CRTP:奇异递归模板模式
浅谈 CRTP:奇异递归模板模式 前言 建议先看一遍文末的参考资料! 建议先看一遍文末的参考资料! 建议先看一遍文末的参考资料! 思维导图 一.CRTP 是什么 CRTP 全称 : Curiously ...
- 浅谈淘宝客运营的一些思路和方法
浅谈淘宝客运营的一些思路和方法 我在之前的文章<如何吸引淘宝客推广你的商品>中提到:值得注意的是淘宝客这种推广方式可能不太适合入门级的淘宝店家,初级店家可以通过爆款等方式在市场上证明自身的 ...
- 浅谈产品事业部“技术管理”思路
浅谈产品事业部"技术管理"思路 本系列文章由ex_net(张建波)编写,转载请注明出处. http://blog.csdn.net/ex_net/article/details/8 ...
最新文章
- 思科高级路由与交换(CISCO 部分) 第5天
- 地图区域划分转换成数学模型解决问题
- python 博弈论 库_SHAP:Python的可解释机器学习库
- mysql purge进程_InnoDB Purge 的工作原理?
- JavaWeb 入门篇(2)Hello Servlet!!!
- win10 LTSC系统 安装应用商店和纸牌合集,解决从应用商店安装Solitaire Collection纸牌打开空白的问题
- SSH实现一个简单的权限控制实例(一)
- 持续技术开放 | SOFAStack 启用独立 Group
- mysql 好用 客户端_5款好用的mysql客户端
- java 生成uuid
- 怎样实现EDIUS中素材小范围精确移动
- php变形的itf条码,itf14条码生成器 第14章生成器.doc
- 普通文档怎么换成php,腾讯在线文档如何转化为普通文档
- React antd antd-mobile修改Switch组件尺寸大小
- html一键打包注册表,离线修改或批量导入目标系统注册表工具(支持PE和挂载系统操作)...
- 多目标进化优化-SPEA/R
- DAGAGUARD追加归档方式迁移到rac集群
- [读书笔记]《Effective Modern C++》—— 移步现代 C++
- 【ATTCK】守株待兔式的水坑攻击
- 3DMAX如何建模手
热门文章
- 解决MySQL查询数据不一致诟病
- 《几何与代数导引》习题1.18——Ceva 定理
- php代码静态分析工具,Wpbullet:一款针对WordPress(PHP)的静态代码分析工具
- onnx 测试_pytorch onnx onnxruntime tensorrt踩坑 各种问题
- 软件测试工程师-软件测试基本介绍
- git tig使用技巧_如何使用Tig浏览Git日志
- 哪种编程语言好找工作_哪种编程语言可以工作? 为了周末?
- angular 创建服务器_使用D3和Angular创建通用的可视化
- 3d打印 开源_Hovalin:开源3D打印小提琴
- Ceres Solver 非线性优化库