ural 1039 没有上司的晚会 树形dp

Description

  Ural大学有N个职员,编号为1~N。他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。每个职员有一个快乐指数。现在有个周年庆宴会,要求与会职员的快乐指数最大。但是,没有职员愿和直接上司一起与会。 

Input

第一行一个整数N。(1<=N<=6000) 
接下来N行,第i+1行表示i号职员的快乐指数Ri。(-128<=Ri<=127) 
接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。 
最后一行输入0,0。

Output

输出最大的快乐指数。

Sample Input

7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0

Sample Output

5

Source

ural 1039


分析:这一道题构成了森林,我们要把它变为一棵树。只要加一个根节点(root,n+1节点),把森林里的每棵树的根都作为root的儿子即可。

  f[i,0]表示不邀请i的最大值,f[i,1]表示邀请i的最大值,f[n+1,0]就是所求,m为的儿子的数量,a[i,k]表示i的第k个儿子。

  f[i,0]=f[i,0]+max(f[a[i,k],0],f[a[i,k],1])   (1<=k<=m)  {不请i可以请i的下属,也可以不请i的下属}

  f[i,1]=f[i,1]+f[a[i,k],0]; (1<=k<=m) {请i一定不能请下属}

var
 a:array [1..6001,0..6001] of longint;
 w:array [1..6001] of longint;
 f:array [1..6001,0..1] of longint;
 b:array [1..6001] of boolean;
 n,x,y,i:longint;
procedure dfs(x:longint);
 var
   i,c:longint;
begin
  b[x]:=false;
  if a[x,0]=0 then
   begin
    f[x,0]:=0;
    f[x,1]:=w[x];
    exit;
   end;
  for i:=1 to a[x,0] do
   if b[a[x,i]] then dfs(a[x,i]);
  for i:=1 to a[x,0] do
   begin
    c:=a[x,i];
    if f[c,1]>f[c,0] then
             f[x,0]:=f[x,0]+f[c,1]
        else f[x,0]:=f[x,0]+f[c,0];
    f[x,1]:=f[x,1]+f[c,0];
   end;
   f[x,1]:=f[x,1]+w[x];
end;

begin
 readln(n);
 for i:=1 to n do
  readln(w[i]);
 for i:=1 to n-1 do
  begin
   readln(x,y);
   inc(a[y,0]);
   a[y,a[y,0]]:=x;
   b[x]:=true;
  end;
 for i:=1 to n do
  begin
   if not b[i] then
    begin
     inc(a[n+1,0]);
     a[n+1,a[n+1,0]]:=i;
    end;
  end;
  fillchar(b,sizeof(b),true);
 dfs(n+1);
 writeln(f[n+1,0]);
end.



你可能感兴趣的:(DP)