codeforces#322 div2 F Zublicanes and Mumocrates 树形dp
http://codeforces.com/contest/581/problem/F
#include<bits/stdc++.h> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) using namespace std; typedef long long ll; const int maxn=5100; const int INF=1e9+10; int n; vector<int> G[maxn]; int dp[maxn][maxn][2]; int rt; int cnt[maxn]; int f[maxn][maxn][2]; int id[maxn]; void dfs1(int u,int f) { cnt[u]=0; int sz=G[u].size(); if(sz==1){ cnt[u]=1;return; } REP(i,0,sz-1){ int v=G[u][i]; if(v==f) continue; dfs1(v,u); cnt[u]+=cnt[v]; } } void dfs(int u,int fa) { int sz=G[u].size(); if(sz==1){ dp[u][0][0]=dp[u][1][1]=0; dp[u][0][1]=dp[u][1][0]=INF; return; } REP(i,0,sz-1){ int v=G[u][i]; if(v==fa) continue; dfs(v,u); } int m=0; REP(i,0,sz-1){ int v=G[u][i]; if(v==fa) continue; id[++m]=v; } int sum=0; REP(i,0,m){ REP(j,0,cnt[u]){ f[i][j][0]=f[i][j][1]=INF; } } f[0][0][0]=f[0][0][1]=0; REP(i,1,m){ int v=id[i]; sum+=cnt[v]; REP(j,0,sum){ REP(k,0,min(cnt[v],j)){ f[i][j][0]=min(f[i][j][0],min(f[i-1][j-k][0]+dp[v][k][0],f[i-1][j-k][0]+dp[v][k][1]+1)); f[i][j][1]=min(f[i][j][1],min(f[i-1][j-k][1]+dp[v][k][1],f[i-1][j-k][1]+dp[v][k][0]+1)); } if(i==m){ dp[u][j][0]=f[i][j][0]; dp[u][j][1]=f[i][j][1]; } } } } int main() { freopen("in.txt","r",stdin); while(cin>>n){ REP(i,1,n) G[i].clear(); REP(i,1,n-1){ int u,v; scanf("%d%d",&u,&v); G[u].push_back(v); G[v].push_back(u); } if(n==2){ puts("1");continue; } REP(i,1,n) if((int)G[i].size()>1) rt=i; dfs1(rt,0); dfs(rt,0); printf("%d\n",min(dp[rt][cnt[rt]/2][0],dp[rt][cnt[rt]/2][1])); } return 0; }
没有AC不了的题,只有不努力的ACMER!