基础的树形dp
f[x][0/1/2]表示选x/不选x x被控制/x不被控制的最小代价
f[x][0]=1+sigma{min(f[x][0],f[x][1],f[x][2])}
f[x][1]=sigma{min(f[y][0],f[y][1])}-max{min(f[y][0],f[y][1])-f[y][0]}
f[x][2]=sigma{f[y][1]}
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> #define inf 10000000 #define maxn 10010 using namespace std; int f[maxn][3],head[maxn],to[2*maxn],next[2*maxn]; int n,m,num; void addedge(int x,int y) { num++;to[num]=y;next[num]=head[x];head[x]=num; } void dfs(int x,int fa) { f[x][0]=1;f[x][2]=0; int mx=-inf; for (int p=head[x];p;p=next[p]) if (to[p]!=fa) { dfs(to[p],x); f[x][0]+=min(f[to[p]][0],min(f[to[p]][1],f[to[p]][2])); f[x][1]+=min(f[to[p]][0],f[to[p]][1]);mx=max(mx,min(f[to[p]][0],f[to[p]][1])-f[to[p]][0]); f[x][2]+=f[to[p]][1]; } f[x][1]-=mx; } int main() { scanf("%d",&n); for (int i=1;i<n;i++) { int x,y; scanf("%d%d",&x,&y); addedge(x,y);addedge(y,x); } dfs(1,0); printf("%d\n",min(f[1][0],f[1][1])); return 0; }