没有上司的舞会
时间: 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。
输出格式
输出最大的快乐指数。
测试样例1
输入
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[..,..]of longint;
x,y:array[..]of longint;
dp:array[..,..]of longint;
i,j,k:longint;
n,len,a,b:longint;
procedure init(a,b:longint);
begin
w[len,]:=b;
if w[a,]=
then w[a,]:=len else w[w[a,],]:=len;
w[a,]:=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,]:=x[a]; dp[a,]:=;
if w[a,]= then exit;
tt:=w[a,];
while tt<> do
begin
dfs(w[tt,]);
inc(dp[a,],dp[w[tt,],]);
inc(dp[a,],max(dp[w[tt,],],dp[w[tt,],]));
tt:=w[tt,];
end;
end;
begin
readln(n); len:=n+; fillchar(y,sizeof(y),);
for i:= to n do
readln(x[i]);
for i:= to n- do
begin readln(a,b); init(b,a); inc(y[a]); end;
for i:= to n do
if y[i]= then begin a:=i; break; end;
dfs(a);
writeln(max(dp[a,],dp[a,]));
end.