首页 > 编程语言 >【C++BFS】802. 找到最终的安全状态

【C++BFS】802. 找到最终的安全状态

时间:2024-08-03 18:28:58浏览次数:17  
标签:auto res C++ BFS vector graph 802 节点

本文涉及知识点

C++BFS算法

LeetCode802. 找到最终的安全状态

有一个有 n 个节点的有向图,节点按 0 到 n - 1 编号。图由一个 索引从 0 开始 的 2D 整数数组 graph表示, graph[i]是与节点 i 相邻的节点的整数数组,这意味着从节点 i 到 graph[i]中的每个节点都有一条边。
如果一个节点没有连出的有向边,则该节点是 终端节点 。如果从该节点开始的所有可能路径都通向 终端节点 ,则该节点为 安全节点 。
返回一个由图中所有 安全节点 组成的数组作为答案。答案数组中的元素应当按 升序 排列。

示例 1:

在这里插入图片描述

输入:graph = [[1,2],[2,3],[5],[0],[5],[],[]]
输出:[2,4,5,6]
解释:示意图如上。
节点 5 和节点 6 是终端节点,因为它们都没有出边。
从节点 2、4、5 和 6 开始的所有路径都指向节点 5 或 6 。
示例 2:

输入:graph = [[1,2,3,4],[1,2],[3,4],[0,4],[]]
输出:[4]
解释:
只有节点 4 是终端节点,从节点 4 开始的所有路径都通向节点 4 。

提示:

n == graph.length
1 <= n <= 104
0 <= graph[i].length <= n
0 <= graph[i][j] <= n - 1
graph[i] 按严格递增顺序排列。
图中可能包含自环。
图中边的数目在范围 [1, 4 * 104] 内。

C++BFS

本题本质是拓扑排序,如果有相应的模板,则用模板,否则用BFS。
预处理:graph记录的是后续的节点,计算vPre前续节点。
BFS的状态:leves[0]记录所有终端节点,leves[i]记录所有边都指向leves[0…i-1]的节点。空间复杂度:O(n)。
BFS的后续状态:cur所有前置节点中,扣掉指向leves[0…i-1]后,出度为0的节点。时间复杂度:O(m),m是边数。注意:不能有重边。
BFS的初始状态:所有终端节点。
BFS的返回值:用一维数组代替二维数组,并排序。
BFS的重复处理:数组出重。

代码

核心代码

class Solution {
		public:
			vector<int> eventualSafeNodes(vector<vector<int>>& graph) {
				const int N = graph.size();
				vector<vector<int>> vPre(N);
				vector<int> vOut(N);
				for (int i = 0; i < graph.size(); i++) {
					for (const auto& next : graph[i]) {
						vPre[next].emplace_back(i);
					}
					vOut[i] = graph[i].size();
				}
				vector<bool> vis(N);
				
				vector<int> v;
				auto Add = [&](int node) {
					if (vis[node]) { return; }
					if (0 != vOut[node]) { return; }	
					v.emplace_back(node);
					vis[node] = true;
				};
				for (int i = 0; i < graph.size(); i++) {
					if(graph[i].empty()){
						Add(i);
					}
				}
				for (int i = 0; i < v.size(); i++) {
					for (const int ip : vPre[v[i]]) {
						vOut[ip]--;
						Add(ip);
					}
				}
				sort(v.begin(), v.end());
				return v;
			}
		};

单元测试

		TEST_METHOD(TestMethod1)
		{
			graph = { {} };
			auto res = Solution().eventualSafeNodes(graph);
			AssertEx(vector<int>{0}, res);
		}
		TEST_METHOD(TestMethod2)
		{
			graph = { {0} };
			auto res = Solution().eventualSafeNodes(graph);
			AssertEx(vector<int>{}, res);
		}
		TEST_METHOD(TestMethod3)
		{
			graph = { {},{} };
			auto res = Solution().eventualSafeNodes(graph);
			AssertEx(vector<int>{0,1}, res);
		}
		TEST_METHOD(TestMethod4)
		{
			graph = { {1},{} };
			auto res = Solution().eventualSafeNodes(graph);
			AssertEx(vector<int>{0, 1}, res);
		}
		TEST_METHOD(TestMethod5)
		{
			graph = { {},{0} };
			auto res = Solution().eventualSafeNodes(graph);
			AssertEx(vector<int>{0, 1}, res);
		}
		TEST_METHOD(TestMethod6)
		{
			graph = { {1},{0} };
			auto res = Solution().eventualSafeNodes(graph);
			AssertEx(vector<int>{}, res);
		}
		TEST_METHOD(TestMethod11)
		{
			graph =  { {1,2},{2,3},{5},{0},{5},{},{} };
			auto res = Solution().eventualSafeNodes(graph);
			AssertEx(vector<int>{2,4,5,6}, res);
		}
		TEST_METHOD(TestMethod12)
		{
			graph = { {1,2,3,4},{1,2},{3,4},{0,4},{} };
			auto res = Solution().eventualSafeNodes(graph);
			AssertEx(vector<int>{4}, res);
		}		


如果有不明白的,请加文末QQ群。如果要打包下载源码(CSDN下载频道偶尔审核不通过,原因未知),也请加QQ群。

扩展阅读

视频课程

先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等

课程
https://edu.csdn.net/lecturer/6176

相关推荐

我想对大家说的话
工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例。重视操作
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛
失败+反思=成功

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本**

算法C++**实现。

标签:auto,res,C++,BFS,vector,graph,802,节点
From: https://blog.csdn.net/he_zhidan/article/details/140491627

相关文章

  • 离散化-c++
    离散化:一、使用情景值域大e.g.0~1e9个数少e.g.0~1e5二、使用方法将数组中的数映射到从0开始的自然数a[]:1、3、100、2000、50000映射到从0开始的自然数:0,1,2,3,4这个过程就是离散化三、两个问题:1.a数组中最开始可能有重复元素,需要去重vector<int>alls;//存......
  • C++ 面向对象基础-构造函数
    目录1.构造函数1.1基本使用1.2函数参数默认值1.3构造初始化列表 1.4隐式调用构造函数2.拷贝构造函数2.1概念2.2浅拷贝2.3深拷贝3.析构函数1.构造函数1.1基本使用构造函数是一种特殊的成员函数,用于创建对象时初始化,写法上有以下要求:●函数名称必......
  • 【C++】实验十五
    题目:1、求一元二次方程ax2+bx+c=0的实根。如果方程没有实根,则利用异常处理处理机制输出有关警告信息2、学校的人事部门保留了有关学生的部分数据(学号、姓名、年龄、住址)。教务部门也保留了学生的另一些数据(学号、姓名、性别,成绩),两个部门分别编写了本部门的学生数据管理程序,其......
  • 【C++】红黑树
     ......
  • C++ 最小生成树 洛谷
    介绍:最小生成树是个啥?其实就像杨志一行人押送生辰纲。抛开最后生辰纲被抢的结局不谈,杨志他们需要到好几个地方,每个地方都需要花点过路费给梁山好汉们打点。比如下面就是一张城市地图:其中每两个图之间的路径长就是要给梁山好汉们打点的银子数。比如1号地点到2号地点的梁山好......
  • 一天速通顺序结构(0基础,软件“Dev-c++”需自己下载)
    今天浅浅带大家速通顺序结构,话不多说,上干货!1,cout语句我们都知道,任何程序都会用到输出,那该怎么实现输出呢,代码实现:#include<iostream>usingnamespacestd;intmain(){cout<<"字符串";cout<<endl;return0;}其中"#include<iostream>"是头文件,起到声明输入输出......
  • C++动态规划(01背包)
    例题1:有 N 个物品,从 1 到 N 编号。对于每个 i(1≤i≤N),物品 i 的重量是 wi​ 价值是 vi​。太郎决定从 N 个物品里选一些放进背包带回家。太郎的背包的容量是 W,因此放进背包的物品的总重量不能超过 W。求太郎带回家的物品的总价值可能达到的最大值。1.贪......
  • 使用C++实现GB28181信令服务中心
    一。背景:   参照开源的GB28181信令服务wvp,准备使用C++实现一套自研的轻量级GB信令服务中心。因此对GB28181协议进行了梳理并且编写了Demo验证,现在把过程整理下来。   希望将来能够实现一套完整的GB28181信令服务。使用了eXosip库。二。GB28181协议栈:三。GB28181信......
  • c++中的标准库
    前言hello,我是文宇。正文C++标准库是C++编程语言的基本组成部分之一,它为开发人员提供了一套丰富和强大的工具和功能,以便快速开发高效、可靠和可移植的应用程序。C++标准库由两个主要部分组成:STL(StandardTemplateLibrary)和非STL部分。STL(标准模板库)是C++标准库的核心部分,......
  • 速通c++(周六)
    前言hello大家好,我是文宇。今天是速通c++的最后一天。(周日是愉快的玩耍,学个毛线)今天是一些用循环写的骚操作(娱乐)正文以下是一些在C++中使用循环进行的有趣和骚操作的例子:打印三角形:intn=5;for(inti=0;i<n;i++){for(intj=0;j<=i;j++){cout......