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;
}
View Code

 

posted @ 2015-12-30 11:52  __560  阅读(202)  评论(0编辑  收藏  举报