哈喽!这里是一只派大鑫,不是派大星。本着基础不牢,地动山摇的学习态度,从基础的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模板思路(一)相关推荐

  1. laytpl语法_浅谈laytpl 模板空值显示null的解决方法及简单的js表达式

    浅谈laytpl 模板空值显示null的解决方法及简单的js表达式 laytpl 模板语法 {{ d.field }} 输出一个普通字段,不转义html 官方的说明 但d.field 为空时会显示nu ...

  2. 借WS2812 PWM DMA驱动调试浅谈STM32调试思路

    借WS2812 PWM DMA驱动调试浅谈STM32调试思路 ​ 接触STM32差不多有4年了,在学校参加比赛时也需要进行各种调试工作,团队的配合也需要个人具有领域内快速定位与解决BUG的能力,前些日 ...

  3. 分布式服务架构的设计方案下—通过业务场景浅谈分布式设计思路

    文章目录 分布式业务场景分析 分布式系统提高承载量的基本手段 并发模型(多线程.异步) 缓存/缓冲 硬件故障 资源利用率优化 软件服务内容更新 数据统计 目录服务 消息队列服务(ActiveMQ.Ze ...

  4. (转)浅谈dedecms模板引擎工作原理及自定义标签

    理解织梦模板引擎有什么意义?一方面可以更好地自定义标签.更多在于了解织梦系统,理解模板引擎是理解织梦工作原理的第一步.理解织梦会使我们写php代码时更顺手,同时能学习一些php代码的组织方式. 这似乎 ...

  5. 浅谈动态规划 ——by cbw

    浅谈动态规划 基本思路 动态规划算法通常用于求解具有某种最优性质的问题.在这类问题中,可能 会有许多可行解.每一个解都对应于一个值,我们希望找到具有最优值的解. 动态规划算法与分治法类似,其基本思想也 ...

  6. php smarty 原理,php模板原理PHP模板引擎smarty模板原理浅谈

    mvc是开发中的一个伟大的思想,使得开发代码有了更加清晰的层次,让代码分为了三层各施其职.无论是对代码的编写以及后期的阅读和维护,都提供了很大的便利. 我们在php开发中,视图层view是不允许有ph ...

  7. 浅谈 CRTP:奇异递归模板模式

    浅谈 CRTP:奇异递归模板模式 前言 建议先看一遍文末的参考资料! 建议先看一遍文末的参考资料! 建议先看一遍文末的参考资料! 思维导图 一.CRTP 是什么 CRTP 全称 : Curiously ...

  8. 浅谈淘宝客运营的一些思路和方法

    浅谈淘宝客运营的一些思路和方法 我在之前的文章<如何吸引淘宝客推广你的商品>中提到:值得注意的是淘宝客这种推广方式可能不太适合入门级的淘宝店家,初级店家可以通过爆款等方式在市场上证明自身的 ...

  9. 浅谈产品事业部“技术管理”思路

    浅谈产品事业部"技术管理"思路 本系列文章由ex_net(张建波)编写,转载请注明出处. http://blog.csdn.net/ex_net/article/details/8 ...

最新文章

  1. 思科高级路由与交换(CISCO 部分) 第5天
  2. 地图区域划分转换成数学模型解决问题
  3. python 博弈论 库_SHAP:Python的可解释机器学习库
  4. mysql purge进程_InnoDB Purge 的工作原理?
  5. JavaWeb 入门篇(2)Hello Servlet!!!
  6. win10 LTSC系统 安装应用商店和纸牌合集,解决从应用商店安装Solitaire Collection纸牌打开空白的问题
  7. SSH实现一个简单的权限控制实例(一)
  8. 持续技术开放 | SOFAStack 启用独立 Group
  9. mysql 好用 客户端_5款好用的mysql客户端
  10. java 生成uuid
  11. 怎样实现EDIUS中素材小范围精确移动
  12. php变形的itf条码,itf14条码生成器 第14章生成器.doc
  13. 普通文档怎么换成php,腾讯在线文档如何转化为普通文档
  14. React antd antd-mobile修改Switch组件尺寸大小
  15. html一键打包注册表,离线修改或批量导入目标系统注册表工具(支持PE和挂载系统操作)...
  16. 多目标进化优化-SPEA/R
  17. DAGAGUARD追加归档方式迁移到rac集群
  18. [读书笔记]《Effective Modern C++》—— 移步现代 C++
  19. 【ATTCK】守株待兔式的水坑攻击
  20. 3DMAX如何建模手

热门文章

  1. 解决MySQL查询数据不一致诟病
  2. 《几何与代数导引》习题1.18——Ceva 定理
  3. php代码静态分析工具,Wpbullet:一款针对WordPress(PHP)的静态代码分析工具
  4. onnx 测试_pytorch onnx onnxruntime tensorrt踩坑 各种问题
  5. 软件测试工程师-软件测试基本介绍
  6. git tig使用技巧_如何使用Tig浏览Git日志
  7. 哪种编程语言好找工作_哪种编程语言可以工作? 为了周末?
  8. angular 创建服务器_使用D3和Angular创建通用的可视化
  9. 3d打印 开源_Hovalin:开源3D打印小提琴
  10. Ceres Solver 非线性优化库