[Tyvj 1052] 没有上司的舞会

没有上司的舞会

时间: 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[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.

你可能感兴趣的:(动态规划—树形DP)