【树形DP】 POJ 1947 Rebuilding Roads

来源:互联网 发布:python中正则表达式 编辑:程序博客网 时间:2024/05/16 10:43

点击打开链接

最少剪去多少条边使得存在一个节点数为P的树

#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>using namespace std;#include<queue>#include <string>#include <sstream>#include <map>#include <vector>#define LL long long#define N 1000100const int INF= 1e8;vector<int>g[191];int dp[189][192];//1 节点 ,2 算上该节点有多少点int n,p,x,y,num[200];int dfs(int u,int pre){    num[u]=1;    for(int i=0;i<g[u].size();i++)    {        int v=g[u][i];        if(v==pre) continue;        num[u]+=dfs(v,u);        for(int j=num[u];j>1;j--)        {            for(int k=1;k<j;k++)            {                dp[u][j]=min(dp[u][j],dp[u][j-k]+dp[v][k]-1);//表示 不剪这条边 先前已经剪过所以需要-1            }        }    }    return num[u];}int main(){    while(scanf("%d%d",&n,&p)!=EOF)    {        for(int i=0;i<=n;i++) g[i].clear();        for(int i=0;i<n-1;i++)        {            cin>>x>>y;            g[x].push_back(y);        }//        memset(dp,-1,sizeof(dp));        for(int i=0;i<=n;i++)            for(int j=0;j<=n;j++) dp[i][j] = INF;        for(int i=0;i<=n;i++) dp[i][1]=g[i].size();//初始化        dfs(1,1);        int ans=dp[1][p];        for(int i=2;i<=n;i++) ans=min(ans,dp[i][p]+1);        cout<<ans<<endl;    }    return 0;}


0 0
原创粉丝点击