时间: 1000ms / 空间: 131072KiB / Java类名: Main
Ural大学有N个职员,编号为1~N。他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。每个职员有一个快乐指数。现在有个周年庆宴会,要求与会职员的快乐指数最大。但是,没有职员愿和直接上司一起与会。
第一行一个整数N。(1<=N<=6000)
接下来N行,第i+1行表示i号职员的快乐指数Ri。(-128<=Ri<=127)
接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。
最后一行输入0,0。
输出最大的快乐指数。
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0
5
dp[i,1]表示选i点的最大值,dp[i,0]表示不选i点的最大值
dp[i,1]=∑dp[son[i],0]
dp[i,0]=∑(dp[son[i],1],dp[son[i],0])max+x[i]
其实树形DP就是找到父节点与子节点之间取那个,或者取几个的问题,用DFS递归着考虑的
var
w:array[0..18005,1..2]of longint;
x,y:array[0..6005]of longint;
dp:array[0..6005,0..1]of longint;
i,j,k:longint;
n,len,a,b:longint;
procedure init(a,b:longint);
begin
w[len,1]:=b;
if w[a,2]=0
then w[a,2]:=len else w[w[a,1],2]:=len;
w[a,1]:=len; inc(len);
end;
function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end;
procedure dfs(a:longint);
var tt:longint;
begin
dp[a,1]:=x[a]; dp[a,0]:=0;
if w[a,2]=0 then exit;
tt:=w[a,2];
while tt<>0 do
begin
dfs(w[tt,1]);
inc(dp[a,1],dp[w[tt,1],0]);
inc(dp[a,0],max(dp[w[tt,1],1],dp[w[tt,1],0]));
tt:=w[tt,2];
end;
end;
begin
readln(n); len:=n+1; fillchar(y,sizeof(y),0);
for i:=1 to n do
readln(x[i]);
for i:=1 to n-1 do
begin readln(a,b); init(b,a); inc(y[a]); end;
for i:=1 to n do
if y[i]=0 then begin a:=i; break; end;
dfs(a);
writeln(max(dp[a,1],dp[a,0]));
end.