传送门
http://tyvj.cn/p/3097
http://tyvj.cn/p/3121
http://tyvj.cn/p/3369
题目大意
给一棵n个节点的树,在点上放置士兵,每个士兵能监视周围的所有边,询问最少放置的士兵数
题解
dp[i,0]表示在i点不放士兵合法的最小放置数dp[i,1]表示在i点放士兵合法的最小放置数
dp[i,0]=∑dp[son[i],1]
dp[i,1]=∑(dp[son[i],1],dp[son[i],0])min
var
w:array[0..7500,1..2]of longint;
dp:array[0..1505,0..1]of longint;
y:array[0..1505]of longint;
i,j,k:longint;
n,a,b,c,len:longint;
procedure init(a,b:longint);
begin
w[len,1]:=b;
if w[a,2]=0
then w[a,2]:=len else w[w[a,1],2]:=len;
w[a,1]:=len; inc(len);
end;
function min(a,b:longint):longint;
begin
if a>b then exit(b) else exit(a);
end;
procedure dfs(a:longint);
var tt:longint;
begin
y[a]:=1; dp[a,0]:=0; dp[a,1]:=1;
if (w[a,1]=w[a,2])and(y[w[w[a,1],1]]=1)
then exit;
tt:=w[a,2];
while tt<>0 do
begin
if y[w[tt,1]]=0 then begin
dfs(w[tt,1]);
inc(dp[a,1],min(dp[w[tt,1],1],dp[w[tt,1],0]));
inc(dp[a,0],dp[w[tt,1],1]);
end;
tt:=w[tt,2];
end;
end;
begin
readln(n); len:=n+1;
for i:=1 to n do begin
read(a,b);
for j:=1 to b do
begin read(c); init(a,c); init(c,a); end;
end;
dfs(0);
writeln(min(dp[0,0],dp[0,1]));
end.