
Solution:
public static long findMaximumSum(int treeNodes, List<Integer> treeFrom,
List<Integer> treeTo, List<Integer> weight) {
Map<Integer, List<Integer>> graph = new HashMap<>();
for (int i = 1; i <= treeNodes; i++) {
graph.put(i, new ArrayList<>());
}
for (int i = 0; i < treeFrom.size(); i++) {
graph.get(treeFrom.get(i)).add(treeTo.get(i));
graph.get(treeTo.get(i)).add(treeFrom.get(i));
}
long[][] dp = new long[treeNodes + 1][2];
boolean[] visited = new boolean[treeNodes + 1];
dfs(1, -1, graph, dp, weight, visited);
return Math.max(dp[1][0], dp[1][1]);
}
private static void dfs(int node, int parent,
Map<Integer, List<Integer>> graph,
long[][] dp, List<Integer> weight,
boolean[] visited) {
visited[node] = true;
dp[node][1] = weight.get(node - 1);
dp[node][0] = 0;
for (int child : graph.get(node)) {
if (child != parent && !visited[child]) {
dfs(child, node, graph, dp, weight, visited);
dp[node][0] += Math.max(dp[child][0], dp[child][1]);
dp[node][1] += dp[child][0];
}
}
}