战略游戏 树形动态规划

题目大意

他要建立一个古城堡,城堡中的路形成一棵树。他要在这棵树的结点上放置最少数目的士兵,使得这些士兵能了望到所有的路。

注意,某个士兵在一个结点上时,与该结点相连的所有边将都可以被了望到。

请你编一程序,给定一树,帮Bob计算出他需要放置最少的士兵.

 

分析

  从根节点出发,先在儿子节点做一次dp.由于儿子节点的放置士兵会影响到跟节点,那么就判断如果儿子节点用了士兵,那么根节点就可以不用放置了。朴素的dp就ok了。

 

代码

 

var
  a:array[0..2000,0..2000] of longint;
  v:array[0..2000] of boolean;
  i,j,k,l:longint;
  n,m:longint;

function dfs(r:longint):longint;
var
  i,j,k:longint;
  c:longint;
begin
  j:=0; k:=0;
  dfs:=0;
  for i:=1 to a[r,0] do
    begin
      c:=a[r,i];
      if a[c,0]=0
        then j:=j+1
        else
          begin
            dfs:=dfs+dfs(c);
            if not v[c]
              then k:=k+1;
          end;
    end;
  if (k>0) or (j>0)
    then
      begin
        dfs:=dfs+1;
        v[r]:=true;
      end;
end;

begin
  readln(n);
  fillchar(v,sizeof(v),1);
  for i:=1 to n do
    begin
      read(j,a[j,0]);
      for k:=1 to a[j,0] do
        begin
          read(l);
          a[j,k]:=l;
          v[l]:=false;
        end;
    end;
  for i:=0 to n-1 do
    if v[i] then break;
  v[i]:=false;
  write(dfs(i));
end.


posted @ 2016-05-08 13:23  一个响亮的蒟蒻  阅读(264)  评论(0编辑  收藏  举报