通过率 78% · 提交 300 · 通过 234
小慕正在研究一个家族财富管理系统,树中的每个节点代表一位家庭成员,节点的数字表示该成员的财富值。一个节点及其所有直接相连的子节点被定义为一个“”。 现在,小慕需要根据给定的这棵树,计算出财富总和最大的小家庭的值。
这类题属于华为 OD 机考真题方向中「100分 / DFS」方向的高频题型,通常考察对「100分 / DFS」的建模能力与边界条件处理。掌握本题的解题思路后,可举一反三应对同类真题方向,稳步提升机考通过率。
提示:带虚线的词点一下有通俗解释。
第一行为一个数N,表示成员总数,成员编号1-N,1<=N<=1000
第二行为N个空格分隔的数,表示编号1-N的成员的财富值,0<=财富值<=1000000
接下来N-1行,每行两个空格分隔的整数(N1,N2),表示N1是N2的父节点。
最富裕的小家庭的财富和
示例 1
输入示例
4 100 200 300 500 1 2 1 3 2 4
输出示例
700
时间限制 1000 ms · 内存限制 128 MB
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。
题目所给的数据形式,非常容易想到转化为邻接表来储存数据。 另外,由于数据所给的编号是从 1 开始 的,为了方便后续对应上财富列表的索引(从 0 开始),可以把 -1 之后的结果 作为编号来储存。
另外,由于本题的输入没有告知根节点 root,我们需要根据输入的 n-1 条边 来找到根节点。 根节点 root 存在特点:根节点 root 不是任何一个节点的子节点。因此,我们可以根据 n-1 条边中的所有子节点,反推出唯一那个不是子节点的节点,即为根节点。具体代码如下:
剩下的就是常规的 DFS 和 BFS 过程了。由于本题所给数据是树型结构(有向无环图),不会出现同一个节点多次进入的情况,因此无需额外使用 check_list 来维护节点重复进入。
对于 DFS 而言,核心函数为:
对于 BFS 而言,核心过程为:
可以发现都涉及相似的过程:
little_family_sum = money_list[i]money_list[ch],更新当前小家庭的总财富值 little_family_sumlittle_family_sum,更新全局的答案 ans另外,本题还存在一种非常简单的解法,无需进行 DFS/BFS 搜索。 由于每一个小家庭仅由父节点和其子节点构成,这里的对应关系可以从边的对应关系中直接得到。 在拿到一条边 (fa, ch) 的时候,实际上我们可以马上知道父节点 fa 和子节点 ch 对应的财富 money_list[fa] 和 money_list[ch]。
仅需额外构建一个列表 little_family_list,little_family_list[i] 表示以 i 为父节点的小家庭的财富。 初始化 little_family_list[i] = money_list[i](这样才能避免父节点的重复计算),然后对于所有的边 (fa, ch),将 fa 的孩子 ch 的财富加入到这个小家庭中(只往小家庭中加入子节点),即 little_family_list[fa] += money_list[ch]。 最后找到 little_family_list 中的最大值即为答案。整体的核心代码如下:
复杂度分析 设 n 为家庭成员(节点)的数量,输入共有 n-1 条父子边。
综上时间复杂度为 O(n),瓶颈就是对 n 个节点、n-1 条边的一次完整遍历。空间复杂度 O(n):邻接表与 childrenSet 各存 O(n) 个元素,DFS 递归栈深度等于树高,最坏(链状树)为 O(n)。
登录后可查看你在本题的历史提交,以及每次的各用例通过情况。
© 2026 广州慕课网络科技有限公司 · 吴师兄学算法官网 版权所有