题目大意
他要建立一个古城堡,城堡中的路形成一棵树。他要在这棵树的结点上放置最少数目的士兵,使得这些士兵能了望到所有的路。
注意,某个士兵在一个结点上时,与该结点相连的所有边将都可以被了望到。
请你编一程序,给定一树,帮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.