hdu 1054 Strategic Game 树形DP

题意:在任意节点放一个士兵可是看守相邻的边。问最少用最少个士兵可以看守所有街道。

分析:很明显的树形DP。

f[i]表示节点i放士兵,g[i]表示不放。

若节点i放,则其子节点放不放都行;若不放,则其子节点全都要放。

代码

var
  n,i,root,u,s,j:longint;
  x:char;
  y:string;
  g,f:array[1..1500] of longint;
  a:array[1..1500,0..1500] of longint;
  v:array[1..1500] of boolean;

procedure dfs(x:longint);
var
  i:longint;
  flag:boolean;
begin
  for i:=1 to a[x,0] do
    dfs(a[x,i]);
  f[x]:=1;
  g[x]:=0;
  flag:=true;
  for i:=1 to a[x,0] do
  begin
    if f[a[x,i]]<=g[a[x,i]]
      then f[x]:=f[x]+f[a[x,i]]
      else f[x]:=f[x]+g[a[x,i]];
    g[x]:=g[x]+f[a[x,i]];
  end;
end;

begin
  while not eof do
  begin
    readln(n);
    fillchar(v,sizeof(v),true);
    for i:=1 to n do
    begin
      read(x);
      y:='';
      while x<>':' do
      begin
        y:=y+x;
        read(x);
      end;
      val(y,u);
      inc(u);
      read(x);
      read(x);
      y:='';
      while x<>')' do
      begin
        y:=y+x;
        read(x);
      end;
      val(y,a[u,0]);
      for j:=1 to a[u,0] do
      begin
        read(s);
        a[u,j]:=s+1;
        v[s+1]:=false;
      end;
      readln;
    end;
    for i:=1 to n do
      if v[i] then
      begin
        root:=i;
        break;
      end;
    dfs(root);
    if f[root]<g[root]
      then writeln(f[root])
      else writeln(g[root]);
  end;
end.


你可能感兴趣的:(hdu 1054 Strategic Game 树形DP)