C++深度优先搜索的应用:在树上执行操作以后得到的最大分数

news/2024/7/20 20:18:55 标签: 深度优先, c++, 算法, 最大分数, 树形DP, 动态规划

涉及知识点

深度优先搜索(DFS)

题目

有一棵 n 个节点的无向树,节点编号为 0 到 n - 1 ,根节点编号为 0 。给你一个长度为 n - 1 的二维整数数组 edges 表示这棵树,其中 edges[i] = [ai, bi] 表示树中节点 ai 和 bi 有一条边。
同时给你一个长度为 n 下标从 0 开始的整数数组 values ,其中 values[i] 表示第 i 个节点的值。
一开始你的分数为 0 ,每次操作中,你将执行:
选择节点 i 。
将 values[i] 加入你的分数。
将 values[i] 变为 0 。
如果从根节点出发,到任意叶子节点经过的路径上的节点值之和都不等于 0 ,那么我们称这棵树是 健康的 。
你可以对这棵树执行任意次操作,但要求执行完所有操作以后树是 健康的 ,请你返回你可以获得的 最大分数
示例 1:
输入:edges = [[0,1],[0,2],[0,3],[2,4],[4,5]], values = [5,2,5,2,1,1]
输出:11
解释:我们可以选择节点 1 ,2 ,3 ,4 和 5 。根节点的值是非 0 的。所以从根出发到任意叶子节点路径上节点值之和都不为 0 。所以树是健康的。你的得分之和为 values[1] + values[2] + values[3] + values[4] + values[5] = 11 。
11 是你对树执行任意次操作以后可以获得的最大得分之和。
示例 2:
输入:edges = [[0,1],[0,2],[1,3],[1,4],[2,5],[2,6]], values = [20,10,9,7,4,3,5]
输出:40
解释:我们选择节点 0 ,2 ,3 和 4 。

  • 从 0 到 4 的节点值之和为 10 。
  • 从 0 到 3 的节点值之和为 10 。
  • 从 0 到 5 的节点值之和为 3 。
  • 从 0 到 6 的节点值之和为 5 。
    所以树是健康的。你的得分之和为 values[0] + values[2] + values[3] + values[4] = 40 。
    40 是你对树执行任意次操作以后可以获得的最大得分之和。
    提示:
    2 <= n <= 2 * 104
    edges.length == n - 1
    edges[i].length == 2
    0 <= ai, bi < n
    values.length == n
    1 <= values[i] <= 109
    输入保证 edges 构成一棵合法的树。

分析

时间复杂度

O(n)。两轮DFS,时间复杂度O(n)。每个节点处理的时间复杂度O(1)。 作为子树的根节点被处理一次,作为儿子节点处理一次。第一轮DFS 记录各节点及子孙节点所有价值。第二轮每个节点有两个选择:一,保留本节点,删除所有孙节点。二,删除本节点,各子节点必须保证各叶子节点健康。
注意
一,叶子节点只能选择方式一。
二,不能用neiBo[cur]的元素数量判断是否是叶子节点,因为里面有父节点。

代码

核心代码

class CNeiBo2
{
public:
CNeiBo2(int n, bool bDirect, int iBase = 0):m_iN(n),m_bDirect(bDirect),m_iBase(iBase)
{
m_vNeiB.resize(n);
}
CNeiBo2(int n, vector<vector>& edges, bool bDirect,int iBase=0) :m_iN(n), m_bDirect(bDirect), m_iBase(iBase)
{
m_vNeiB.resize(n);
for (const auto& v : edges)
{
m_vNeiB[v[0]- iBase].emplace_back(v[1]- iBase);
if (!bDirect)
{
m_vNeiB[v[1]- iBase].emplace_back(v[0]- iBase);
}
}
}
inline void Add(int iNode1, int iNode2)
{
iNode1 -= m_iBase;
iNode2 -= m_iBase;
m_vNeiB[iNode1].emplace_back(iNode2);
if (!m_bDirect)
{
m_vNeiB[iNode2].emplace_back(iNode1);
}
}
const int m_iN;
const bool m_bDirect;
const int m_iBase;
vector<vector> m_vNeiB;
};

class Solution {
public:
long long maximumScoreAfterOperations(vector<vector>& edges, vector& values) {
m_c = edges.size() + 1;
m_values = values;
m_vTotal.resize(m_c);
m_vRet.resize(m_c);
CNeiBo2 neiBo(m_c, edges, false);
DFS(0, -1, neiBo.m_vNeiB);
return DFS2(0, -1, neiBo.m_vNeiB);
}
void DFS(int cur, int parent, const vector<vector>& neiBo)
{
long long& curTotal = m_vTotal[cur];
curTotal = m_values[cur];
for (const auto& next : neiBo[cur])
{
if (next == parent)
{
continue;
}
DFS(next, cur, neiBo);
curTotal += m_vTotal[next];
}
}
long long DFS2(int cur, int parent, const vector<vector>& neiBo)
{
//保留本节点,其它权删除
long long curScore = m_vTotal[cur] - m_values[cur];
//删除本节点
long long curScore2 = m_values[cur];
bool bHasChild = false;
for (const auto& next : neiBo[cur])
{
if (next == parent)
{
continue;
}
curScore2 += DFS2(next, cur, neiBo);
bHasChild = true;
}
if (!bHasChild)
{
curScore2 = 0;
}
return m_vRet[cur] = max(curScore, curScore2);
}
int m_c;
vector m_vTotal;
vector m_vRet;
vector m_values;
long long m_llRet = 0;
};

测试用例

遗失。

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《闻缺陷则喜算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

鄙人想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
墨家名称的来源:有所得以墨记之。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17


http://www.niftyadmin.cn/n/5154831.html

相关文章

【代码】【5 二叉树】d3

关键字&#xff1a; 非叶子结点数、k层叶子结点数、层次遍历、找双亲结点、找度为1、叶子结点数

【linux编程】linux文件IO的标准函数及其示例(fopen,fclose,freopen)

标准IO函数是C语言库提供的一组用于文件输入输出操作的函数,它们在stdio.h头文件中定义,可以在不同的操作系统和平台上使用,具有可移植性和简便性的优点。标准IO函数通过文件流(FILE*)来操作文件,文件流是一个结构体指针,包含了文件的信息和缓冲区,可以对文件进行缓冲和…

华为政企协作平板产品集

产品类型产品型号产品说明 IdeaHub系列IFP-UG86EIdeaHub系列 | 4K柔光屏 | 智慧妙笔 | 企业级信息安全IdeaHub系列IHB2- 65SUIdeaHub系列 | 4K 柔光屏 | 25ms流畅板书 | 安全智慧教学IdeaHub系列IHB2- 75SUIdeaHub系列 | 4K 柔光屏 | 25ms流畅板书 | 安全智慧教学IdeaHu…

微服务使用指南

微服务使用指南 1.初识微服务 微服务可以认为是一种分布式架构的解决方案&#xff0c;提供服务的独立性和完整性&#xff0c;做到服务的高内聚、低耦合。 目前服务架构主要包含&#xff1a;单体架构和分布式架构。 1.1 单体架构 单体架构&#xff1a;把所有业务功能模块都…

如何用 GPT-4 全模式(All Tools)帮你高效学习和工作?

「十项全能」的 ChatGPT &#xff0c;用起来感受如何&#xff1f; 之前&#xff0c;作为 ChatGPT Plus 用户&#xff0c;如果你集齐下面这五个模式&#xff0c;就会成为别人羡慕的对象。 但现在&#xff0c;人们更加期盼的&#xff0c;是下面这个提示的出现&#xff1a; 这个提…

UE4 Niagara Module Script 初次使用笔记

这里可以创建一个Niagara模块脚本 创建出来长这样 点击号&#xff0c;输出staticmesh&#xff0c;点击它 这样就可以拿到对应的一些模型信息 这里的RandomnTriCoord是模型的坐标信息 根据坐标信息拿到位置信息 最后的Position也是通过Map Set的号&#xff0c;选择Particles的P…

8.接口与抽象类 深入多态

8.1 不该初始化的class 这个结构有什么不对&#xff1f; 这个class结构不算太差。如此设计已经能够维持最少的重复程序代码&#xff0c;且有需要特地实现的方法也已经被覆盖过。从多态的角度来看&#xff0c;我们也做到了适应性&#xff0c;所以任何Animal的子型&#xff0c;包…

超纯试剂纯化研发实验室建设要求分析

超纯试剂通常是指用于药品研发和生产的高纯度化学试剂&#xff0c;这些试剂的纯度和质量对药品的安全性和有效性具有重要影响。超纯试剂纯化研发实验室主要是研究和开发新的超纯试剂及其制备方法&#xff0c;以确保其符合医药领域对试剂质量的要求。这些实验室通常配备有先进的…