//再水一发树形dp
1 #include "iostream" 2 #include "cstdio" 3 #include "cstring" 4 #include "algorithm" 5 using namespace std; 6 int dp[6010][2]; 7 bool vis[6010]; 8 int tot, first[6010], next[6010], to[6010]; 9 int n, ans[6010]; 10 void dfs(int root) 11 { 12 vis[root] = 1; 13 dp[root][1] = ans[root]; 14 int edge; 15 for(edge = first[root]; edge; edge = next[edge]) { 16 dfs(to[edge]); 17 dp[root][0] += max(dp[to[edge]][0], dp[to[edge]][1]); 18 dp[root][1] += dp[to[edge]][0]; 19 } 20 } 21 22 int main() 23 { 24 int i; 25 scanf("%d", &n); 26 for(i = 1; i <= n; ++i) 27 scanf("%d", &ans[i]); 28 int b, a; 29 tot = 0; 30 int root = n * (n + 1); 31 root >>= 1; 32 while(scanf("%d%d", &b, &a) && (a || b)) { 33 next[++tot] = first[a]; 34 first[a] = tot; 35 to[tot] = b; 36 root -= b; 37 } 38 dfs(root); 39 printf("%d\n", max(dp[root][0], dp[root][1])); 40 }