f[i][0]表示被父亲守
f[i][1]表示被自己守
f[i][2]表示被儿子守
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #define MN 15500 #define re register int using namespace std; int f[MN][3]; int cnt,head[MN]; int n,m,k,a[MN]; int vis[MN]; struct child{ int v,nxt; }e[2*MN]; void add(int u,int v){ e[++cnt].v=v; e[cnt].nxt=head[u]; head[u]=cnt; } void dp(int u,int fa){ //f[u][0]=f[u][2]=a[u]; //f[u][1]=0; int d=0x3f3f3f3f; for(re i=head[u];i;i=e[i].nxt){ int v=e[i].v; if(v==fa)continue; dp(v,u); f[u][0]+=min(f[v][1],f[v][2]); f[u][1]+=min(f[v][1],f[v][2]); f[u][2]+=min(f[v][0],min(f[v][1],f[v][2])); d=min(d,f[v][2]-min(f[v][2],f[v][1])); //f[u][2]-min(f[v][1],f[v][2])表示其它儿子的总和。 } f[u][1]+=d;f[u][2]++; } int main(){ scanf("%d",&n); for(re i=1;i<=n-1;i++){ int a1,a2,a3,a4; scanf("%d%d",&a1,&a2); add(a1,a2); add(a2,a1); } dp(1,0); printf("%d\n",min(f[1][1],f[1][2])); return 0; }