BZOJ 1596: [Usaco2008 Jan]电话网络 树形DP
挺经典的,细节需要特别注意一下
Code:
#include<bits/stdc++.h> using namespace std; #define setIO(s) freopen(s".in","r",stdin) #define maxn 20003 #define inf 10000000 int edges; int hd[maxn],to[maxn],nex[maxn],f[maxn][4]; void add(int u,int v) { nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; } void dfs(int u,int fa) { int sum=0; f[u][0]=0, f[u][2]=1, f[u][1]=inf; for(int i=hd[u];i;i=nex[i]) { int v=to[i]; if(v==fa) continue; dfs(v,u); f[u][0]+=f[v][1], f[u][2]+=min(f[v][0],min(f[v][1], f[v][2])), sum+=min(f[v][1], f[v][2]); } for(int i=hd[u];i;i=nex[i]) { int v=to[i]; if(v==fa) continue; f[u][1]=min(f[u][1], sum+f[v][2]-min(f[v][2],f[v][1])); } } int main() { // setIO("input"); int i,j,n,x,y; scanf("%d",&n); for(i=1;i<n;++i) { scanf("%d%d",&x,&y); add(x,y), add(y,x); } dfs(1,0); printf("%d\n",min(f[1][1],f[1][2])); return 0; }