树形dp的入门经典题目。
import java.util.*;
public class Main {
public static List<Integer> son[];
public static int w[],dp[][]; //0no 1yes
public static void main(String[] args)
{
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
son=new ArrayList[n+1];
w=new int[n+1];
dp=new int[n+1][2];
for(int i=1;i<=n;i++)w[i]=sc.nextInt();
int v[]=new int[n+1];
for(int i=0;i<n-1;i++){
int s=sc.nextInt();
v[s]=1;
int f=sc.nextInt();
if(son[f]==null)
son[f]=new ArrayList<Integer>();
son[f].add(s);
}
int root=-1;
for(int i=1;i<=n;i++){
if(v[i]==0){
root=i;
break;
}
}
//System.out.println(root);
dfs(root);
System.out.println(Math.max(dp[root][1],dp[root][0]));
}
public static void dfs(int cur){
if(son[cur]==null){
dp[cur][0]=0;
dp[cur][1]=w[cur];
return;
}
for(int i=0;i<son[cur].size();i++){
int curson=son[cur].get(i);
dfs(curson);
dp[cur][0]+=Math.max(dp[curson][0],dp[curson][1]);
dp[cur][1]+=dp[curson][0];
}
dp[cur][1]+=w[cur];
return;
}
}