poj1947(树形dp)

src:http://poj.org/problem?id=1947

ac代码:

#include <iostream>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<functional>
#include<utility>
#include<string>
#include<string.h>
#include<vector>
#include<iomanip>
#include<stack>
using namespace std;
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define Max(a,b) a=max(a,b)
#define Min(a,b) a=min(a,b)
const int inf=99999999;

int n,p,dp[151][151],sz[151],num[151];
vector<int>head[151];//sz[]表示树u有几个结点,num[]表示有个子节点

void init(){FOR(i,1,n)FOR(j,1,n)dp[i][j]=inf;FOR(i,1,n)head[i].clear();memset(sz,0,sizeof(sz));memset(num,0,sizeof(num));}
void add_edge(int u,int v){head[u].push_back(v);}
void dfs1(int u,int fa)
{
    sz[u]=1;
    for(int i=0;i<head[u].size();i++){
        int v=head[u][i];
        if(v==fa)continue;
        dfs1(v,u);
        num[u]++;
        sz[u]+=sz[v];
    }
}
void dfs2(int u,int fa)
{
    dp[u][1]=num[u];
    for(int i=0;i<head[u].size();i++){
        int v=head[u][i];
        if(v==fa)continue;
        dfs2(v,u);
        for(int j=sz[u];j>=2;j--)for(int k=1;k<=sz[v];k++)if(j>k){
            Min(dp[u][j],dp[u][j-k]+dp[v][k]-1);
        }
    }
}

int main()
{
    ios::sync_with_stdio(false);
    while(cin>>n>>p){
        init();
        int a,b;
        FOR(i,1,n-1){cin>>a>>b;add_edge(a,b);add_edge(b,a);}
        dfs1(1,-1);
        dfs2(1,-1);
        int ans=dp[1][p];
        FOR(i,2,n)Min(ans,dp[i][p]+1);
        cout<<ans<<endl;
    }
    return 0;
}

 

posted @ 2018-05-18 23:35  WindFreedom  阅读(126)  评论(0)    收藏  举报