/* 树形DP 而然我并不知道树在哪(....) f[x][0]表示x节点不参加舞会 以x为根的子树的最优解 f[x][1]表示x节点参加舞会 以x为根的子树的最优解 方程为:(so为x的儿子 so要枚举一下) f[x][0]+=max(f[so][0],f[so][1]); f[x][1]+=f[so][0]; 初始化 f[i][1]= 输入的happy值 最后比较 max(f[i][0],f[i][1]) i为根 */ #include<iostream> #include<cstdio> #include<cstring> #define maxn 6010 using namespace std; int f[maxn][3],son[maxn][maxn],n,fa[maxn],x,y; void Dfs(int x) { for(int i=1;i<=son[x][son[x][0]];i++) { int so=son[x][i]; Dfs(so); f[x][0]+=max(f[so][0],f[so][1]); f[x][1]+=f[so][0]; } } int main() { scanf("%d",&n); int i,j; for(i=1;i<=n;i++) { scanf("%d",&f[i][1]); fa[i]=i; } while(1) { scanf("%d%d",&x,&y); if(x==0&&y==0)break; son[y][++son[y][0]]=x; fa[x]=y; } for(i=1;i<=n;i++) if(fa[i]==i) { Dfs(i); printf("%d ",max(f[i][0],f[i][1])); } return 0; }