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

news2024/10/5 9:31:15

图论基础知识

学习记录自代码随想录

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.coloradmin.cn/o/1625433.html

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

相关文章

Find My头盔|苹果Find My技术与头盔结合,智能防丢,全球定位

头盔是保护头部的装具&#xff0c;是人们交通中不可或缺的工具。头盔具有保护头部、吸收冲击力、减少伤害风险、提高安全性、防止颅脑损伤等功效作用。头盔能够提供额外的保护&#xff0c;减少头部受伤的风险。在日常出行或进行高风险活动过程中&#xff0c;如骑自行车、骑行电…

http忽略ssl认证

我们在发请求时&#xff0c;会遇到需要ssl证书验证的报错&#xff0c;针对该错误以及所使用的不同的创建连接的方式&#xff0c;进行ssl证书忽略 忽略SSL证书的流程 简介&#xff1a;需要告诉client使用一个不同的TrustManager。TrustManager是一个检查给定的证书是否有效的类…

mybatis的使用技巧9——mysql按年、季度、月、周等不同时间维度查询或分组统计

在实际项目开发过程中&#xff0c;按不同时间维度查询业务数据的操作异常频繁。比较多的操作如支持按时间周期范围做列表数据的筛选&#xff0c;或者是按年月日等维度的图表展示&#xff0c;亦或者是首页的概况&#xff0c;三维大屏的展示等&#xff0c;都离不开不同时间周期查…

Pulsar【部署 02】Pulsar可视化工具Manager安装使用

Pulsar Manager 是一个基于 web 的 GUI 管理和监视工具&#xff0c;可帮助管理员和用户管理和监视租户、命名空间、主题、订阅、代理、集群等&#xff0c;并支持对多个环境进行动态配置。 可视化工具Manager安装使用 1.Docker1.1 拉取镜像并启动1.2 设置用户名密码1.3 登录并添…

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

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

【提示学习】PromptSync论文问题汇总

文章目录 PromptSync: Bridging Domain Gaps in Vision-Language Models through Class-Aware Prototype Alignment and Discrimination&#xff08;2024CVPR&#xff09;1 Introduction2 Related Work2.1 CLIP2.2 TPT 3 Methodology3.1 提出方法PromptSync3.2 类感知原型生成&…

Cgicc搭建交叉编译环境(移植到arm)

Cgicc GUN Project官网连接&#xff1a;Cgicc- GNU Project - Free Software Foundation 1. 下载源码 Cgicc下载地址&#xff1a; [via http] Index of /gnu/cgicc [via FTP] ftp://ftp.gnu.org/gnu/cgicc/ 目前最新版&#xff1a;3.2.20 2. 源码构建原理 一般&#xff…

POCEXP编写—EXP编写实战(1)

TOC 1. 前言 通过上一篇文章的了解&#xff0c;应该都了解了POC是怎么编写的&#xff0c;而且POC和EXP的区别就是POC只能验证漏洞&#xff0c;简单来说就是通过判断特定的响应值来判断是否存在漏洞&#xff0c;而且EXP就需要将响应的内容给返回回来&#xff0c;但是整体在编写…

vue中的mixin(局部混入、全局混入)

一、mixin是什么 Mixin是面向对象程序设计语言中的类&#xff0c;提供了方法的实现。其他类可以访问mixin类的方法而不必成为其子类&#xff1b;Mixin类通常作为功能模块使用&#xff0c;在需要该功能时“混入”&#xff0c;有利于代码复用又避免了多继承的复杂 Vue中的mixin…

低空经济概念

低空经济是指利用低空空域资源&#xff0c;通过低空交通工具和技术创新发展&#xff0c;促进航空产业、旅游、物流、紧急救援等多领域经济增长和产业融合。随着科技的不断进步和航空产业的快速发展&#xff0c;低空经济正逐渐成为全球经济的重要组成部分。 一、低空经济的主要特…

大数据计算引擎中的Calcite

1.Calcite介绍 Calcite是一个动态数据库管理框架&#xff0c;具备数据库管理系统的功能 Calcite具备SQL解析、校验、优化、生成、连接查询等功能 Calcite能够为不同平台和数据源提供统一的查询引擎 2.Calcite能力 比如&#xff0c;对于HBase而言&#xff0c;没有SQL查询的能力…

✨“光纤通信新篇章:BiDi单纤模块的原理与应用”

&#x1f4a1;目录 ❓什么是BiDi单纤模块&#xff1f; &#x1f527;BiDi光模块的工作原理 &#x1f31f;BiDi光模块的优势 &#x1f335;BiDi光模块类型介绍 &#x1f320;BiDi SFP光模块 &#x1f320;BiDi SFP光模块 &#x1f320;BiDi X2光模块 &#x1f320;BiDi …

科技论文网站:中国科技论文在线

文章目录 1. Intro2. Main3. Cons Evaluation彩蛋&#xff1a;科学素质 这是作者最后一次发这种级别的科普文章 1. Intro 中国科技论文在线是经教育部批准&#xff0c;由教育部科技发展中心主办&#xff0c; 利用现代信息技术手段&#xff0c;打破传统出版物的概念&#xff0c…

NLP step by step -- 了解Transformer

Transformer模型 Transformer相关历史 首先我们先看一下有关Transformer模型的发展历史&#xff0c;下面的图是基于Transformer架构的一些关键模型节点&#xff1a; 图片来源于Hugging Face 图片来源于Hugging Face Transformer 架构 于 2017 年 6 月推出。原本研究的重点是…

GITEE 基于OAuth2的API V5版本

为了构建更好的码云生态环境&#xff0c;我们推出了基于OAuth2的API V5版本。 API V5接口使用方式以及Url都参照GitHub&#xff0c;为了各位开发者更好的兼容已经存在的第三方应用。 API 使用条款 OSCHINA 用户是资源的拥有者&#xff0c;需尊重和保护用户的权益。不能在应用…

信创需求激增,国产服务器操作系统赋能数字化转型

信创&#xff0c;即信息技术应用创新&#xff0c;是指在关键领域和环节推进信息技术的自主创新&#xff0c;构建安全可控的信息技术体系。随着数字化转型的加速&#xff0c;信创需求激增&#xff0c;国产服务器操作系统在其中扮演着至关重要的角色。国产服务器操作系统如何赋能…

TikTok营销攻略:如何精准测试与优化品牌营销策略

在当今数字营销的世界中&#xff0c;社交媒体平台已成为吸引目标受众的重要工具。而TikTok&#xff0c;作为一个快速崛起的视频分享平台&#xff0c;在年轻人中享有巨大的流行度。对于那些希望利用这一平台进行营销的品牌和营销人员来说&#xff0c;了解如何在TikTok上测试营销…

[Rust开发]在Rust中使用geos的空间索引编码实例

geos的空间索引用的是STRTree&#xff0c;这是一种基于STR算法的四叉树索引&#xff0c;有如下特点&#xff1a; 使用Sort-Tile-Recursive (STR) 算法创建的仅查询的R-tree空间索引 STR(Sort-Tile-Recursive,递归网格排序) 基本思想是将所有的矩形以“tile”的方式分配到r/n&a…

使用Azure AI Search和LlamaIndex构建高级RAG应用

RAG 是一种将公司信息合并到基于大型语言模型 &#xff08;LLM&#xff09; 的应用程序中的常用方法。借助 RAG&#xff0c;AI 应用程序可以近乎实时地访问最新信息&#xff0c;团队可以保持对其数据的控制。 在 RAG 中&#xff0c;您可以评估和修改各个阶段以改进结果&#x…

大型企业高效内部协同,向日葵SDK私有化部署案例解析

大型集团企业的内部&#xff0c;沟通协作的重要性不言而喻&#xff0c;我们时常能听到关于所谓“大企业病”的吐槽&#xff0c;多数也是源于企业内部沟通协作效率低&#xff0c;进而导致内耗加重。甚至我们可以这么说&#xff0c;越是发展壮大的集团企业&#xff0c;其内部的沟…