最简单的树形dp,树上最大点权独立集
import java.util.Scanner;
public class Main{
static class Edge{
int v,next;
Edge(int v,int next){
this.v=v;
this.next=next;
}
}
static final int N=(int)6e3+50;
static final int M=(int)2e4+50;
static int n,u,v,cnt;
static int[] head=new int[N];
static int[][] dp=new int[N][2];
static boolean[] ind=new boolean[N];
static Edge[] edges=new Edge[M];
static void init(){
cnt=0;
for(int i=1;i<=n;i++){
head[i]=-1;
}
}
static void addEdge(int u,int v){
edges[cnt]=new Edge(v,head[u]);
head[u]=cnt++;
}
static void dfs(int u){
for(int i=head[u];i!=-1;i=edges[i].next){
int v=edges[i].v;
dfs(v);
dp[u][1]+=dp[v][0];
dp[u][0]+=Math.max(dp[v][0],dp[v][1]);
}
}
public static void main(String[] args) {
Scanner cin=new Scanner(System.in);
while(cin.hasNext()){
n=cin.nextInt();
init();
for(int i=1;i<=n;i++){
ind[i]=false;
dp[i][0]=dp[i][1]=0;
}
for(int i=1;i<=n;i++){
dp[i][1]=cin.nextInt();
}
while(cin.hasNext()){
v=cin.nextInt();
u=cin.nextInt();
if(v+v==0){
break;
}
addEdge(u,v);
ind[v]=true;
}
int root=-1;
for(int i=1;i<=n;i++){
if(!ind[i]){
root=i;
break;
}
}
dfs(root);
System.out.println(Math.max(dp[root][0],dp[root][1]));
}
}
}