首页 > 编程语言 >【C++ 图论 DFS】1443. 收集树上所有苹果的最少时间|1682

【C++ 图论 DFS】1443. 收集树上所有苹果的最少时间|1682

时间:2024-10-26 17:18:55浏览次数:3  
标签:vector false int DFS hasApple edges 1443 true 1682

在这里插入图片描述

本文涉及知识点

C++图论
C++DFS

LeetCode1443. 收集树上所有苹果的最少时间

给你一棵有 n 个节点的无向树,节点编号为 0 到 n-1 ,它们中有一些节点有苹果。通过树上的一条边,需要花费 1 秒钟。你从 节点 0 出发,请你返回最少需要多少秒,可以收集到所有苹果,并回到节点 0 。
无向树的边由 edges 给出,其中 edges[i] = [fromi, toi] ,表示有一条边连接 from 和 toi 。除此以外,还有一个布尔数组 hasApple ,其中 hasApple[i] = true 代表节点 i 有一个苹果,否则,节点 i 没有苹果。
示例 1:
在这里插入图片描述

输入:n = 7, edges = [[0,1],[0,2],[1,4],[1,5],[2,3],[2,6]], hasApple = [false,false,true,false,true,true,false]
输出:8
解释:上图展示了给定的树,其中红色节点表示有苹果。一个能收集到所有苹果的最优方案由绿色箭头表示。
示例 2:
在这里插入图片描述

输入:n = 7, edges = [[0,1],[0,2],[1,4],[1,5],[2,3],[2,6]], hasApple = [false,false,true,false,false,true,false]
输出:6
解释:上图展示了给定的树,其中红色节点表示有苹果。一个能收集到所有苹果的最优方案由绿色箭头表示。
示例 3:

输入:n = 7, edges = [[0,1],[0,2],[1,4],[1,5],[2,3],[2,6]], hasApple = [false,false,false,false,false,false,false]
输出:0

提示:
1 <= n <= 105
edges.length == n - 1
edges[i].length == 2
0 <= ai < bi <= n - 1
hasApple.length == n

后序DFS

DFS(cur) 返回 是否有苹果,收集所有的苹果需要的时间。
由于是树(连通、无环图),故只有一个父节点,用父节点除重。
如果子树没有苹果无需访问。 否则总时间:2 + 子树需要的时间。

代码

核心代码

class CNeiBo
{
public:	
	static vector<vector<int>> Two(int n, vector<vector<int>>& edges, bool bDirect, int iBase = 0) 
	{
		vector<vector<int>>  vNeiBo(n);
		for (const auto& v : edges)
		{
			vNeiBo[v[0] - iBase].emplace_back(v[1] - iBase);
			if (!bDirect)
			{
				vNeiBo[v[1] - iBase].emplace_back(v[0] - iBase);
			}
		}
		return vNeiBo;
	}	
	static vector<vector<std::pair<int, int>>> Three(int n, vector<vector<int>>& edges, bool bDirect, int iBase = 0)
	{
		vector<vector<std::pair<int, int>>> vNeiBo(n);
		for (const auto& v : edges)
		{
			vNeiBo[v[0] - iBase].emplace_back(v[1] - iBase, v[2]);
			if (!bDirect)
			{
				vNeiBo[v[1] - iBase].emplace_back(v[0] - iBase, v[2]);
			}
		}
		return vNeiBo;
	}	
	static vector<vector<int>> Mat(vector<vector<int>>& neiBoMat)
	{
		vector<vector<int>> neiBo(neiBoMat.size());
		for (int i = 0; i < neiBoMat.size(); i++)
		{
			for (int j = i + 1; j < neiBoMat.size(); j++)
			{
				if (neiBoMat[i][j])
				{
					neiBo[i].emplace_back(j);
					neiBo[j].emplace_back(i);
				}
			}
		}
		return neiBo;
	}
};

class Solution {
		public:
			int minTime(int n, vector<vector<int>>& edges, vector<bool>& hasApple) {
				auto neiBo = CNeiBo::Two(n, edges, false, 0);
				function<pair<bool, int>(int, int)> DFS = [&](int cur, int par) {
					int time = 0;
					bool bHas = hasApple[cur];
					for (const auto& next : neiBo[cur]) {
						if (par == next) { continue; }
						auto [b, t] = DFS(next, cur);
						if (!b) { continue; }
						time += 2 + t;
						bHas = true;
					}
					return make_pair( bHas,time );
				};
				auto [tmp,ans] = DFS(0, -1);
				return ans;
			}			
		};

单元测试

int n;
		vector<vector<int>> edges;
		vector<bool> hasApple;
		TEST_METHOD(TestMethod11)
		{
			n = 7, edges = { {0,1},{0,2},{1,4},{1,5},{2,3},{2,6} }, hasApple = { false,false,true,false,true,true,false };
			auto res = Solution().minTime(n, edges, hasApple);
			AssertEx(8, res);
		}
		TEST_METHOD(TestMethod12)
		{
			n = 7, edges = { {0,1},{0,2},{1,4},{1,5},{2,3},{2,6} }, hasApple = { false,false,true,false,false,true,false };
			auto res = Solution().minTime(n, edges, hasApple);
			AssertEx(6, res);
		}
		TEST_METHOD(TestMethod13)
		{
			n = 7, edges = { {0,1},{0,2},{1,4},{1,5},{2,3},{2,6} }, hasApple = { false,false,false,false,false,false,false };
			auto res = Solution().minTime(n, edges, hasApple);
			AssertEx(0, res);
		}

扩展阅读

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

视频课程

先学简单的课程,请移步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++**实现。

标签:vector,false,int,DFS,hasApple,edges,1443,true,1682
From: https://blog.csdn.net/he_zhidan/article/details/143188972

相关文章

  • fastdfs管理工具Go-fastdfs-web 安装教程
    Go-fastdfs-web安装教程安装步骤下载:前往官方下载页面下载所需版本,选择带或不带JRE的安装包。设置权限:给安装文件赋予执行权限,命令为chmod+xgoFastDfsWeb.sh。启动与停止:启动命令为./goFastDfsWeb.shstart,停止为stop,查看状态为status。配置与访问:默认端口为80......
  • DFS与BFS
    图论:一、图中DFS与BFS数和图的存储方式:m与n^2一个级别属于稠密图,m与n一个级别则属于稀疏图,可以从题目中明显看出来稠密图:邻接矩阵稀疏图:邻接表#include<bits/stdc++.h>usingnamespacestd;constintN=100100;intm,n;inth[N],e[N],ne[N],idx;intq[N],d[N];bool......
  • HDFS 重要机制之 checkpoint
    核心概念hdfscheckpoint机制对于namenode元数据的保护至关重要,是否正常完成检查点是评估hdfs集群健康度和风险的重要指标editslog:对hdfs操作的事务记录,类似于wal,editlog文件以edits_开头,后面跟一个txid范围段,并且多个editlog之间首尾相连,正在使用的editl......
  • hadoop_hdfs详解
    HDFS秒懂HDFS定义HDFS优缺点优点缺点HDFS组成架构NameNodeDataNodeSecondaryNameNodeClientNameNode工作机制元数据的存储启动流程工作流程SecondaryNameNode工作机制checkpoint工作流程DataNode工作机制工作流程数据完整性文件块大小块太小的缺点块太大的缺点文......
  • dfs题目:平衡二叉树(java)
    平衡二叉树题目思路开始的error代码(最后一行return的地方有误)修正的代码题目链接:平衡二叉树题目题目思路用分治的思想,要想看看以root为根节点的二叉树是不是平衡二叉树,得看他的左子树和右子树是不是平衡二叉树,如果左子树和右子树都是平衡的,且root自己是平衡的......
  • .netcore 使用PdfSharpCore生成pdf
    想实现的功能是pdf+签名图片合并起来,后面看到了免费开源的PdfSharpCore. 先安装 publicstaticclassPdfSharpCoreHelper{privatestaticstringGetOutFilePath(stringname){stringOutputDirName=@".";return......
  • hdfs的分布式存储原理
    1.想要把一个大文件存储到hdfs,首先进行划分,将文件划分为一个一个的block,这个block默认为512MB,可修改.2.备份(也就是副本)将文件划分后,一个block丢失则原来的大文件没有用了.为了确保文件的安全性,hdfs提供了副本,也就是备份,将文件划分之后hdfs默认将每一个block备份到......
  • 【并查集+dfs】codeforces 1833 E. Round Dance
    题意输入一个正整数\(T(1\leqT\leq10^4)\),表示接下来输入\(T\)组测试用例,对于每一个测试用例:第一行,输入一个正整数\(n(2\leqn\leq2*10^5)\)第二行,输入\(n\)个正整数\(a_i(1\leqa_i\leqn)\),表示节点\(i\)到节点\(a_i\)存在一条有向边,保证无自环这\(n......
  • hdfs集群的shell操作
    1.进程启停管理:一键启动hdfs集群: start-dfs.sh一键关闭hdfs集群: stop-dfs.sh单独控制进程启停:hadoop-daemon.sh(start|status|stop)(namenode|datanode|secondarynamenode)     或者hadoop--daemon(start|status|stop)(namenode|datanode......
  • 1601 添加运算符 枚举 递归dfs
    #include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;constintN=1e3+10,inf=0x3f3f3f3f;inta[N],vis[N];intn,ans;//计算函数:根据运算符i对sum和a[x]进行运算intcal(intsum,inti,intx){if(i==1)returnsum+a[x];//加法......