SSL 1230 战略游戏 树形dp

题意:有一棵树,若在某个节点上放一个士兵则与该节点相连的边都会被看到。问最少放多少个士兵可以看到所有的边。


分析:很明显的树形dp。f[i]表示节点i放士兵且以i为根的树的边全被看到最少放的士兵数。g[i]表示节点i不放士兵且以i为根的树的边全被看到最少放的士兵数。

f[i]=sum(min(f[soni],g[soni]))+1

g[i]=sum(f[soni])


真是不爽一开始看错题目把边看成了点,弄得我调了好久,差点还以为数据和标程都是错的。

看来看清楚题目真的很重要啊!!!


代码:

var
  n,x,y,z,i,j,root:longint;
  f,g,d:array[0..1500] of longint;
  a:array[0..1500,0..1500] of longint;

function min(x,y:longint):longint;
begin
  if x<y then exit(x)
         else exit(y);
end;

procedure dp(x:longint);
var
  i:longint;
begin
  for i:=1 to a[x,0] do
    dp(a[x,i]);
  f[x]:=1;
  g[x]:=0;
  for i:=1 to a[x,0] do
  begin
    f[x]:=f[x]+min(f[a[x,i]],g[a[x,i]]);
    g[x]:=g[x]+f[a[x,i]];
  end;
end;

begin
  readln(n);
  for i:=1 to n do
  begin
    read(x,y);
    for j:=1 to y do
    begin
      read(z);
      inc(a[x,0]);
      a[x,a[x,0]]:=z;
      inc(d[z]);
    end;
    readln;
  end;
  for i:=0 to n-1 do
    if d[i]=0 then
    begin
      root:=i;
      break;
    end;
  dp(root);
  writeln(min(f[root],g[root]));
end.


你可能感兴趣的:(SSL 1230 战略游戏 树形dp)