题目描述
整个公司的人员结构可以看作是一棵标准的多叉树。树的头节点是公司唯一的老板,除老板外,每个员工都有唯一的直接上级,叶节点是没有任何下属的基层员工,除基层员工外,每个员工都有一个或多个直接下级,另外每个员工都有一个快乐值。
这个公司现在要办 party,你可以决定哪些员工来,哪些员工不来。但是要遵循如下的原则:
1.如果某个员工来了,那么这个员工的所有直接下级都不能来。
2.派对的整体快乐值是所有到场员工快乐值的累加。
3.你的目标是让派对的整体快乐值尽量大。
给定一棵多叉树,请输出派对的最大快乐值。
输入描述:
第一行两个整数 n 和 root,n 表示公司的总人数,root 表示公司的老板。
第二行 n 个整数 happy_i 表示员工 i 的快乐值。
接下来 n - 1 行每行两个整数 u_i 和 v_i 表示 u_i 是 v_i 的直接上级。
输出描述:
输出一个整数表示最大快乐值。
示例1
输入
3 1
5 1 1
1 2
1 3
输出
5
解法一:递归
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] info = br.readLine().trim().split(" ");
int len = Integer.parseInt(info[0]);
int r = Integer.parseInt(info[1]);
TreeNode[] nodes = new TreeNode[len+1];
String[] happys = br.readLine().trim().split(" ");
for(int i=1;i<=len;i++){
nodes[i] = new TreeNode(Integer.parseInt(happys[i-1]));
}
createTree(nodes,br);
TreeNode root = nodes[r];
ResultType res = findMax(root);
System.out.println(Math.max(res.withXmax,res.noXmax));
}
public static ResultType findMax(TreeNode node){
if(node==null) return new ResultType(0,0);
List<TreeNode> list = node.list;
int withXmax = node.happy;
int noXmax = 0;
for(TreeNode n:list){
ResultType tmp = findMax(n);
withXmax += tmp.noXmax;
noXmax += Math.max(tmp.withXmax,tmp.noXmax);
}
return new ResultType(withXmax,noXmax);
}
public static void createTree(TreeNode[] nodes,BufferedReader br) throws Exception{
for(int i=0;i<nodes.length-2;i++){
String[] datas = br.readLine().trim().split(" ");
int data = Integer.parseInt(datas[0]);
int child = Integer.parseInt(datas[1]);
nodes[data].list.add(nodes[child]);
}
}
}
class ResultType{
int withXmax;
int noXmax;
public ResultType(int withXmax,int noXmax){
this.withXmax = withXmax;
this.noXmax = noXmax;
}
}
class TreeNode{
int happy;
List<TreeNode> list = new ArrayList<>();
public TreeNode(int happy){
this.happy = happy;
}
}