#P3023. 传递悄悄话(100分)
          
                        
                                    
                      
        
              - 
          
          
                      1000ms
            
          
                      Tried: 142
            Accepted: 65
            Difficulty: 5
            
          
          
          
                       所属公司 : 
                              华为od
                                
            
                      
          
 
- 
                        算法标签>DFS          
 
传递悄悄话(100分)
思路:遍历二叉树
把问题抽象出来,其实就是给定一颗二叉树,每个节点都有对应的权值,问从根节点出发到任意一个节点的路径之和的最大值。
可以使用DFS或者BFS求解,由于题目给的输入数据已经给定了各个节点的子节点的关系,对于下标为i的节点,它的左孩子的节点为i∗2,右孩子的节点为i∗2+1,但是,需要把下标映射到从1开始,才正确,具体参考下面代码
JavaScript
const readline = require('readline');
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});
let w = [0];  // 用于存储树节点值的数组,初始值为[0]
let n, res;  // 树的节点数和最大和
rl.on('line', (line) => {  // 当从输入流中读取一行数据时触发回调函数
  if (!n) {  // 如果节点数n未定义,说明是第一行输入
    w = w.concat(line.split(' ').map(Number));  // 将输入的字符串转换为数字并追加到数组w中
    n = w.length;  // 获取数组w的长度,即树的节点数
    res = 0;  // 初始化最大和为0
    function dfs(u, sum) {  // 定义深度优先搜索函数
      if (u >= n || w[u] === -1) {  // 如果节点索引超出范围或节点的值为-1(表示叶节点),则返回
        return;
      }
      res = Math.max(res, sum + w[u]);  // 更新最大和为当前最大和和当前路径和的最大值
      dfs(u * 2, sum + w[u]);  // 递归调用dfs函数,处理左子节点
      dfs(u * 2 + 1, sum + w[u]);  // 递归调用dfs函数,处理右子节点
    }
    dfs(1, 0);  // 调用深度优先搜索函数,从根节点开始,初始和为0
    console.log(res);  // 输出最大和
    rl.close();  // 关闭输入流
  }
})
C++
#include <iostream>
#include <vector>
#include <sstream> // 添加这行
using namespace std;
vector<int> w;  // 用于存储树节点值的数组
int n, res = 0;  // 树的节点数和最大和
void dfs(int u, int sum) {  // 深度优先搜索函数,接受两个参数:一个节点索引u和从根节点到当前节点的值之和sum
    if (u >= n || w[u] == -1) {  // 如果节点索引超出范围或节点的值为-1(表示叶节点),则返回
        return;
    }
    res = max(res, sum + w[u]);  // 更新最大和为当前最大和和当前路径和的最大值
    dfs(2 * u, sum + w[u]);  // 递归调用dfs函数,处理左子节点
    dfs(2 * u + 1, sum + w[u]);  // 递归调用dfs函数,处理右子节点
}
int main() {
    string input;
    getline(cin, input);  // 从标准输入读取一行
    stringstream ss(input);  // 使用字符串流处理输入
    int num;
    w.push_back(0);  // 在数组开头添加一个虚拟元素,使索引从1开始
    while (ss >> num) {
        w.push_back(num);  // 将读取的整数存入数组
    }
    n = w.size();  // 获取数组的长度,即树的节点数
    dfs(1, 0);  // 调用深度优先搜索函数,从根节点开始,初始和为0
    cout << res << endl;  // 输出最大和
    return 0;
}
Python
w=[0]+list(map(int,input().split()))  # 从输入中读取一个整数列表,并在列表开头添加一个0
n=len(w)  # 获取列表的长度
res=0  # 初始化一个变量来存储最大和
def dfs(u,sum):  # 定义一个函数dfs,它接受两个参数:一个节点索引u和从根节点到当前节点的值之和sum
    if u>=n or w[u]==-1:  # 如果节点索引超出范围或节点值为-1(表示叶节点),则返回
        return
    global res  # 使用全局变量res
    res=max(res,sum+w[u])  # 更新res为其当前值和sum加上当前节点值的最大值
    dfs(u*2,sum+w[u])  # 递归调用dfs函数,传入左子节点和更新后的sum
    dfs(u*2+1,sum+w[u])  # 递归调用dfs函数,传入右子节点和更新后的sum
    
dfs(1,0)  # 以初始和为0调用dfs函数,传入根节点
print(res)  # 打印最大和
Java
import java.util.Scanner;
public class Main {
    static int[] w;  // 用于存储树节点值的数组
    static int n;  // 树的节点数
    static int res = 0;  // 用于存储最大和的变量
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);  // 创建一个Scanner对象来读取输入
        String[] wStr = scanner.nextLine().split(" ");  // 读取一行输入并按空格分割成字符串数组
        n = wStr.length + 1;  // 计算树的节点数
        w = new int[n];  // 初始化存储节点值的数组
        for (int i = 1; i < n; i++) {
            w[i] = Integer.parseInt(wStr[i - 1]);  // 将字符串数组转换为整数并存入w数组
        }
        dfs(1, 0);  // 调用深度优先搜索函数,从根节点开始,初始和为0
        System.out.println(res);  // 打印最大和
    }
    static void dfs(int u, int sum) {
        if (u >= n || w[u] == -1) {  // 如果节点索引超出范围或节点的值为-1(表示叶节点),则返回
            return;
        }
        res = Math.max(res, sum + w[u]);  // 更新最大和为当前最大和和当前路径和的最大值
        dfs(2 * u, sum + w[u]);  // 递归调用dfs函数,处理左子节点
        dfs(2 * u + 1, sum + w[u]);  // 递归调用dfs函数,处理右子节点
    }
}
        题目描述
给定一个二叉树,每个节点上站一个人,节点数字表示父节点到该节点传递悄悄话需要花费的时间。初始时,根节点所在位置的人有一个悄悄话想要传递给其他人,求二叉树所有节点上的人都接收到悄悄话花费的时间。
输入描述
给定二叉树
0 9 20 -1 -1 15 7 -1 -1 -1 -1 3 2
注:-1表示空节点

输出描述
返回所有节点都接收到悄悄话花费的时间
38
样例1
输入
0 9 20 -1 -1 15 7 -1 -1 -1 -1 3 2
输出
38