重点是处理多叉树的输入。用List<List<Integer>>保存父节点的所有子节点。
通过记录每个结点是否有父节点来找root。
public class Main {
public static void main(String[] args) {
//树形dp
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[] scores = new int[n];
for(int i = 0; i < n; i++){
scores[i] = scanner.nextInt();
}
//处理邻接表
List<List<Integer>> nodes = new ArrayList<>();
boolean[] father = new boolean[n];
for(int i = 0; i < n; i++){
nodes.add(new ArrayList<>());
}
for(int i = 1; i < n; i++){
int l = scanner.nextInt()-1;//员工
int k = scanner.nextInt()-1;//上司
nodes.get(k).add(l);
father[l] = true;
}
//找到root
int root = 0;
for(int i = 0; i < n; i++){
if(!father[i]){
root = i;
}
}
int[][] dp = new int[n][2];
dfs(dp,nodes,scores,root,n);
System.out.println(Math.max(dp[root][0],dp[root][1]));
}
private static void dfs(int[][] dp, List<List<Integer>> nodes,int[] scores, int root, int n) {
List<Integer> children = nodes.get(root);
dp[root][1] = scores[root];
if(children.size() != 0){
for(int child: children){
dfs(dp,nodes,scores,child,n);
dp[root][1] += dp[child][0];//选择该结点,则子节点不可选择
dp[root][0] += Math.max(dp[child][0],dp[child][1]);//不选该节点,子节点可选可不选
}
}
}
}