#include<iostream> #include<cmath> #include<algorithm> #include<vector> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> using namespace std; #define maxn 6005 struct node{ int to,net; }que[maxn<<1]; int head[maxn]; int n; int dp[maxn][2],father[maxn];//dp[i][0]0表示不去,dp[i][1]1表示去了 bool visited[maxn]; int tot=0; void addedge(int u,int v){ que[tot].to=v; que[tot].net=head[u]; head[u]=tot++; que[tot].to=u; que[tot].net=head[v]; head[v]=tot++; } void tree_dp(int node) { int i; visited[node] = 1; for(i=head[node]; i!=-1; i=que[i].net) { int v=que[i].to; if(!visited[v]&&father[v] == node)//i为下属 { tree_dp(v);//递归调用孩子结点,从叶子结点开始dp //关键 ) dp[node][1] += dp[v][0];//上司来,下属不来 dp[node][0] +=max(dp[v][1],dp[v][0]);//上司不来,下属来、不来 } } } int main() { int i; int f,c,root; while(scanf("%d",&n)!=EOF) { tot=0; memset(head,-1,sizeof(head)); memset(dp,0,sizeof(dp)); memset(father,0,sizeof(father)); memset(visited,0,sizeof(visited)); for(i=1; i<=n; i++) { scanf("%d",&dp[i][1]); } root = 0;//记录父结点 bool beg = 1; while (scanf("%d %d",&c,&f),c||f) { addedge(c,f); father[c] = f; if( root == c || beg ) { root = f; } } while(father[root])//查找父结点 root=father[root]; tree_dp(root); int imax=max(dp[root][0],dp[root][1]); printf("%d ",imax); } return 0; }