天天看点

[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[..,..]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.