传送门
这道题显然是树DP
我们用F(u,color)表示以u为节点的子树所需的最少节点数,且u刷成color。
F(i,0)表示点i涂黑色,dp(i,1)表示点i涂白色
所以有F(i,0) = sum(min(dp(i.son,1),dp(i.son,0)))
当点i涂黑色时,他涂黑色的儿子可以少涂一个点,i涂白色时同理
然后就是沙比树形dp了。
uses math;
var
vi,a,b,c,fa:array [0..30005] of longint;
dp:array [0..10005,0..1] of longint;
n,m,i,ans,sum,le,x,y:longint;
procedure dfs(x:longint);
var p,c0,c1:longint;
begin
if (x<=n) then exit;
vi[x]:=1; p:=c[x]; c0:=0; c1:=0;
while (p<>0) do begin
if (vi[a[p]]=1) then begin
if (fa[x]=a[p]) then begin vi[x]:=0; exit; end;
fa[x]:=a[p]; p:=b[p]; continue;
end;
dfs(a[p]); c0:=c0+dp[a[p],0]; c1:=c1+dp[a[p],1];
p:=b[p];
end;
dp[x,0]:=min(c1+1,c0); dp[x,1]:=min(c0+1,c1);
if (x=i) then sum:=min(c1+1,c0+1);
vi[x]:=0;
end;
procedure add(x,y:longint);
begin inc(le); a[le]:=y; b[le]:=c[x]; c[x]:=le; end;
begin
fillchar(fa,sizeof(fa),1);
read(m,n);
for i:=1 to n do begin read(x); inc(dp[i,1-x]); end;
for i:=1 to m-1 do begin read(x,y); add(x,y); add(y,x); end;
sum:=0;
dfs(i);
write(sum);
end.