图论基础知识 深度优先(Depth First Search, 简称DFS),广度优先(Breathe First Search, 简称DFS)

图论基础知识

学习记录自代码随想录

dfs 与 bfs 区别

dfs是沿着一个方向去搜,不到黄河不回头,直到搜不下去了,再换方向(换方向的过程就涉及到了回溯)。
bfs是先把本节点所连接的所有节点遍历一遍,走到下一个节点的时候,再把连接节点的所有节点遍历一遍,搜索方向更像是广度,四面八方的搜索过程。

深度优先搜索理论(Depth First Search, 简称DFS)

搜索方向,是认准一个方向搜,直到碰壁之后再换方向
换方向是撤销原路径,改为节点链接的下一个路径,回溯的过程。

回溯算法模板

// 1.确定返回值和参数
void backtracking(参数){// 2.确定回溯终止条件if(终止条件){// 存放结果;return;	}// for横向遍历for(选择:本层集合中元素(树种节点孩子的数量就是集合的大小)){处理节点;// 纵向遍历backtracking(路径,选择列表); // 递归回溯,撤销处理结果}
}

回溯算法模板,其实就是dfs框架

// 1.确定递归函数返回值和参数,一般无返回值
一般情况下深搜需要二维数组结构保存所有路径,需要一维数组保存单一路径,
可定义全局变量
vector<vector<int>> result; // 保存符合条件的所有路径
vector<int> path; // 起点到终点的路径
void dfs(参数){// 2.确定回溯终止条件if(终止条件){// 存放结果;return;	}// 3.处理目前节点出发的路径// for横向遍历for(选择:本节点所连接的其他节点){处理节点;// 纵向遍历dfs(图,选择的节点); // 递归回溯,撤销处理结果}
}

广度优先搜索(Breath First Search, 简称BFS)

广搜的使用场景
广搜的搜索方式就适合于解决两个点之间的最短路径问题。
因为广搜是从起点出发,以起始点为中心一圈一圈进行搜索,一旦遇到终点,记录之前走过的节点就是一条最短路。
当然,也有一些问题是广搜 和 深搜都可以解决的,例如岛屿问题,这类问题的特征就是不涉及具体的遍历方式,只要能把相邻且相同属性的节点标记上就行。 (我们会在具体题目讲解中详细来说)
在这里插入图片描述

正是因为BFS一圈一圈的遍历方式,所以一旦遇到终止点,那么一定是一条最短路径。
在这里插入图片描述

广搜代码模板(针对四方格地图)

int dir[4][2] = {0, 1, 1, 0, -1, 0, 0, -1};  // 表示四个方向
// grid为二维数组,地图
// visited标记访问过的节点
void bfs(vector<vector<char>>& grid, vector<vector<bool>>& visited, int x, int y){que<pair<int, int>> que;  // 定义队列que.push({x,y});  // 起始点加入队列visited[x][y] = true;  // 只要加入队列,立刻标记为访问过的节点while(!que.empty()){pair<int, int> cur = que.front();que.pop();  // 从队列种取元素int cur_x = cur.first;int cur_y = cur.second;for(int i = 0; i < 4; i++){  // 从开始节点的四个方向上右左下遍历// 获取周边四个节点坐标int next_x = cur_x + dir[i][0];int next_y = cur_y + dir[i][1]; // 坐标越界直接跳过if(next_x < 0 || next_x >= grid.size() || next_y < 0 || next_y >= grid.size()){continue;}// 若节点未被访问过if(!visited[next_x][nenxt_y]){// 队列添加新节点供下一轮遍历que.push({next_x, next_y});// 只要加入队列,代表被访问过,进行标记,防止重复访问visited[next_x][next_y] = true;	}}}
}

例题:华为20240410机考

//第二题 会议通知转发总人数
//在一个办公区内,有一些正在办公的员工,当员工A收到会议通知,
//他会将这个会议通知转发给周围四邻(上下左右工位的同事)团队内的同事,
//周围收到该邮件的同事会继续转发给周围四邻(上下左右工位的同事团队内的同事,
//直到周围没有再需要往下传播的同事则会停止;同时此扩散还有前提条件,给定一可收到该邮件的团队列表relations, 
//扩散时若该同事所在团队在relations列表中,则可进行扩散,否则不可进行扩散。
//办公室用一个二维数组office表示,其中office[i][j]表示该同事的团队名称,
//其中团队名称用整数t范围内的数字表示,i,j表示该同事的工位位置。
//
//现给定办公区的工位总行数与每一行的具体工位人员分布以及收到会议通知员工A的工位位置的坐标位置i,j : 
//还有与该邮件关联的团队编号列表relations, 请分析得出最终会有多少同事收到该会议的转发通知。
//
//注意:1、该办公区位置用二维数组表示,该二维数组以左上角的工位为起点(0, 0), 
//按照横轴向右纵轴向下的方向展开;原始收到会议通知的员工A不包含在总人数中。
//2、扩散时若该同事与收到初始收到邮件的员工A属于同一团队,
//若该团队名不在可收到通知的团队列表relations中,依然不可收到该邮件转发//输入
//第一行是一个整数n, 表示该办公区共有多少排,即就是office.length
//第二行是一个整数m, 标识该办公区共有多少列,即就是offce[i].length
//接下来n行表示每一排员工的具体分布情况,每个工位上的员工所在的团队号x用空格隔开
//接下来一行是两个数字用空格隔开,表示收到会议通知员工的工位位置,i表示横坐标位置,j表示纵坐标位置
//最后一行是一个字符串,表示可收到该邮件的团队列表relations, 团队名称之间用空格隔开
//提示:
//0 <= i <= 1000
//0 <= j <= 1000
//1 <= t <= 50
//1 <= relations.length <= 50//输出
//输出收到转发会议通知的总人数。//样例输入1
//5
//5
//1 3 5 2 3
//2 2 1 3 5
//2 2 1 3 3
//4 4 1 1 1
//1 1 5 1 2
//2 2
//1
//样例输出1
//5//样例输入2
//2
//2
//1 1
//2 2
//0 0
//2
//样例输出2
//2#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <queue>
#include <algorithm>using namespace std;class Solution {
public:int getmaxNum(vector<vector<int>>& office, vector<vector<bool>>& visited, int i, int j, vector<int>& relations) {int dir[4][2] = { 0, 1, 1, 0, -1, 0, 0, -1 };int cnt = 0;queue<pair<int, int>> que;que.push({ i, j });visited[i][j] = 1;while (!que.empty()){auto cur = que.front();que.pop();int cur_x = cur.first, cur_y = cur.second;for (int k = 0; k < 4; k++) {int next_x = cur_x + dir[k][0];int next_y = cur_y + dir[k][1];if (next_x < 0 || next_x >= office.size() || next_y < 0 || next_y >= office[0].size()) continue;if (!visited[next_x][next_y] && (find(relations.begin(), relations.end(), office[next_x][next_y]) != relations.end())) {que.push({ next_x, next_y });visited[next_x][next_y] = true;cnt++;}}}return cnt;}
};int main() {int n;cin >> n;cin.ignore();int m;cin >> m;// cin >> m;后直接调用getline, 相当于读取了一个换行符'\n'cin.ignore();vector<vector<int>> office(n);for (int i = 0; i < n; i++) {string line;getline(cin, line);istringstream iss(line);int k;while (iss >> k) {office[i].push_back(k);}}int i, j;cin >> i >> j;cin.ignore();string s;getline(cin, s);vector<int> relations;istringstream iss(s);int temp;while (iss >> temp) {relations.push_back(temp);}vector<vector<bool>> visited(n, vector<bool>(m, false));Solution sol;int result = sol.getmaxNum(office, visited, i, j, relations);cout << result;return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从单按键状态机思维扫描引申到4*4矩阵按键全键无冲扫描,一步一步教,超好理解,超好复现(STM32程序例子HAL库)

目前大部分代码存在的问题 ​ 单次只能对单个按键产生反应&#xff1b;多个按键按下就难以修改&#xff1b;并且代码耦合度较高&#xff0c;逻辑难以修改&#xff0c;对于添加长按&#xff0c;短按&#xff0c;双击的需求修改困难。 解决 16个按键按下无冲&#xff0c;并且代…

如何在CentOS本地搭建DataEase数据分析服务并实现远程查看数据分析

文章目录 前言1. 安装DataEase2. 本地访问测试3. 安装 cpolar内网穿透软件4. 配置DataEase公网访问地址5. 公网远程访问Data Ease6. 固定Data Ease公网地址 前言 DataEase 是开源的数据可视化分析工具&#xff0c;帮助用户快速分析数据并洞察业务趋势&#xff0c;从而实现业务…

【项目分享】用 Python 写一个桌面倒计日程序!

事情是这样的&#xff0c;我们班主任想委托我做一个程序&#xff0c;能显示还有几天考试。我立即理解了这个意思&#xff0c;接下了这个项目。 话不多说&#xff0c;来看看这个项目吧—— 项目简介 仓库地址&#xff1a;https://gitee.com/yaoqx/desktop-countdown-day 这是 …

幻兽帕鲁中文怎么设置 游戏中文修改方法 《幻兽帕鲁》宠物指定配种显示英文解决方法 幻兽帕鲁Steam游戏解说合集 Mac玩Windows游戏

在广阔的世界中收集神奇的生物“帕鲁”&#xff0c;派他们进行战斗、建造、做农活&#xff0c;工业生产等&#xff0c;这是一款支持多人游戏模式的全新开放世界生存制作游戏。幻兽帕鲁支持多人在线捕捉“帕鲁”&#xff0c;展开丰富的冒险玩法&#xff1b;不同的关卡具有不同的…

Bellman Ford算法:解决负权边图的最短路径问题

Bellman Ford算法的介绍 在计算机科学的世界中&#xff0c;Bellman Ford算法是一种解决单源最短路径问题的算法&#xff0c;它可以处理有负权边的图。这个算法的名字来源于两位科学家Richard Bellman和Lester Randolph Ford&#xff0c;他们是这个算法的发明者。 这个算法的主…

AI图书推荐:2024年ChatGPT副业搞钱指南

本书《2024年ChatGPT副业搞钱指南》&#xff08;ChatGPT Side Hustles 2024&#xff09;由Alec Rowe撰写&#xff0c;旨在指导读者如何利用ChatGPT技术来提升被动收入、创造新的现金流&#xff0c;并在数字化时代保持领先。 本书是深入了解被动收入未来的综合指南。本书揭示了超…

【算法基础实验】图论-基于DFS的连通性检测

基于DFS的连通性检测 理论基础 在图论中&#xff0c;连通分量是无向图的一个重要概念&#xff0c;特别是在处理图的结构和解析图的组成时。连通分组件表示图中的一个子图&#xff0c;在这个子图中任意两个顶点都是连通的&#xff0c;即存在一条路径可以从一个顶点到达另一个顶…

Flutter应用下拉菜单设计DropdownButtonFormField控件介绍

文章目录 DropdownButtonFormField介绍使用方法重点代码说明属性解释 注意事项 DropdownButtonFormField介绍 Flutter 中的 DropdownButtonFormField 是一个用于在表单中选择下拉菜单的控件。它是 DropdownButton 和 TextFormField 的组合&#xff0c;允许用户从一组选项中选择…

井字棋游戏

1. 游戏创建 1.1导包 from tkinter import * import numpy as np import math import tkinter.messagebox 1.2 窗口内容 1.2.1创建一个窗口 root Tk() # 窗口名称 root.title("井字棋 from Sun") 1.2.2 创建一个框架&#xff0c;将其放置在窗口中 Frame1 F…

汽车底盘域的学习笔记

前言&#xff1a;底盘域分为传统车型底盘域和新能源车型底盘域&#xff08;新能源系统又可以分为纯电和混动车型&#xff0c;有时间可以再研究一下&#xff09; 1&#xff1a;传统车型底盘域 细分的话可以分为四个子系统 传动系统 行驶系统 转向系统 制动系统 1.1传动系…

什么样的内外网文档摆渡,可以实现安全高效传输?

内外网文档摆渡通常指的是在内网&#xff08;公司或组织的内部网络&#xff09;和外网&#xff08;如互联网&#xff09;之间安全地传输文件的过程。这个过程需要特别注意安全性&#xff0c;因为内网往往包含敏感数据&#xff0c;直接连接内网和外网可能会带来安全风险。因此会…

设计模式——终止模式之两阶段终止模式

文章目录 1. 错误思路2. 两阶段终止模式2.1 利用 isInterrupted2.2 利用停止标记interrupt-打断park Two Phase Termination 在一个线程 T1 中如何“优雅”终止线程 T2&#xff1f;这里的【优雅】指的是给 T2 一个料理后事的机会。 1. 错误思路 使用线程对象的 stop() 方法停…

GEM TSU Interface Details and IEEE 1588 Support

摘要&#xff1a;Xilinx ZNYQ ULTRASCALE MPSOC的GEM和1588的使用 对于FPGA来说&#xff0c;只需要勾选一些znyq的配置就行了&#xff0c;其余的都是软件的工作&#xff1b; 所有配置都勾选之后&#xff0c;最终会露出来的接口如下&#xff1a; GEM需要勾选的配置如下&#xf…

15.Blender Eevee和Cycles渲染引擎对比

初步介绍 Eevee是实时渲染的引擎&#xff0c;会省略一些解算方式&#xff0c;尤其对光线和阴影 Cycles会考虑这些因素&#xff0c;所以会对光线和阴影的表达更加真实&#xff0c;有一个实时光线追踪的功能 Cycles渲染完之后&#xff0c;每移动一次画面&#xff0c;都会重新渲染…

政安晨:【Keras机器学习示例演绎】(十九)—— 可视化网络学习内容

目录 简介 设置 建立特征提取模型 设置梯度上升过程 设置端到端滤波器可视化回路 可视化目标层中的前 64 个滤波器 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras机器学习实战 希望政安晨的博客能够对您有所裨益&…

基于Rust的多线程 Web 服务器

构建多线程 Web 服务器 在 socket 上监听 TCP 连接解析少量的 HTTP 请求创建一个合适的 HTTP 响应使用线程池改进服务器的吞吐量优雅的停机和清理注意&#xff1a;并不是最佳实践 创建项目 ~/rust ➜ cargo new helloCreated binary (application) hello package~/rust ➜ma…

kaggle之皮肤癌数据的深度学习测试

kaggle之皮肤癌数据的深度学习测试 近期一直在肝深度学习 很久之前&#xff0c;曾经上手搞过一段时间的深度学习&#xff0c;似乎是做轮胎花纹的识别&#xff0c;当初用的是TensorFlow&#xff0c;CPU版本的&#xff0c;但已经很长时间都没弄过了 现在因为各种原因&#xff…

全面解析平台工程与 DevOps 的区别与联系

平台工程的概念非常流行&#xff0c;但很多开发人员仍然不清楚它是如何实际运作的&#xff0c;这是非常正常的。 平台工程是与 DevOps 并行吗&#xff1f;还是可以相互替代&#xff1f;或者 DevOps 和平台工程是两个完全不同的概念&#xff1f; 一种比较容易将两者区分开来的方…

打包的意义 作用等前端概念集合 webpack基础配置等

基础网页是什么&#xff1f; 在学校最基础的三剑客 原生JS CSS H5就可以开发静态网页了 对于浏览器而言也能识别这些基础的文件和语法&#xff0c;真正的所见即所得&#xff0c;非常直接。 为什么要使用框架库&#xff1f; 对于常用的前端框架而言&#xff0c;无论是Vue Rea…

普通屏幕已过时?裸眼3D屏幕显示效果更胜一筹!

随着多媒体技术的迅猛进步&#xff0c;我们日常生活中的内容展现方式&#xff0c;已经经历了前所未有的变革。在这其中&#xff0c;裸眼3D屏幕的应用&#xff0c;无疑是最为引人注目的亮点&#xff0c;它相较于传统屏幕&#xff0c;在显示效果上展现出了鲜明的优势&#xff0c;…