http://www.lydsy.com/JudgeOnline/problem.php?id=1596
给定一棵树,每个点可以放置一个物品覆盖这个点直接连接的点,询问最少物品数
树形DP
dp[i,1] :i放物品,使i和i的子树中节点都被覆盖的最小物品数
dp[i,2] :i不放物品,使i和i的子树中节点都被覆盖的最小物品数
dp[i,3] :i不放物品,i不被覆盖,i的子树中节点都被覆盖的最小物品数
dp[i,1]=1+∑min(dp[son[i],1],dp[son[i],2],dp[son[i],3])
dp[i,3]=∑dp[son[i],2]
dp[i,2]=∑min(dp[son[i],1],dp[son[i],2])+dp[son[i],1]−min(dp[son[i],1],dp[son[i],2])
var
dp:array[0..10005,1..3]of longint;
x,y:array[0..10005]of longint;
w:array[0..20005,1..2]of longint;
i,j,k:longint;
a,b,c:longint;
n,m,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(a) else exit(b);
end;
procedure dfs(a:longint);
var tt,s:longint;
begin
x[a]:=1; tt:=w[a,2]; dp[a,1]:=1; dp[a,2]:=0; dp[a,3]:=0; s:=n;
while tt<>0 do
begin
if x[w[tt,1]]=0 then begin
dfs(w[tt,1]);
dp[a,1]:=dp[a,1]+min(min(dp[w[tt,1],1],dp[w[tt,1],2]),dp[w[tt,1],3]);
dp[a,2]:=dp[a,2]+min(dp[w[tt,1],1],dp[w[tt,1],2]);
s:=min(s,dp[w[tt,1],1]-min(dp[w[tt,1],1],dp[w[tt,1],2]));
dp[a,3]:=dp[a,3]+dp[w[tt,1],2];
end;
tt:=w[tt,2];
end;
dp[a,2]:=dp[a,2]+s;
end;
begin
readln(n); len:=n+1;
for i:=1 to n-1 do
begin
readln(a,b);
init(a,b); init(b,a);
end;
dfs(1);
writeln(min(dp[1,1],dp[1,2]));
end.