您的位置:首页 > 其它

poj 1947 树形dp(求一颗树最少经过几次剪枝,可以得到特定大小的子树)

2017-04-28 07:16 483 查看
#include<cstdio>
#include<cstring>
#define MIN(x,y) ((x)>(y)?(y):(x))
struct node
{
int to,next;
}e[200];
int head[200],cnt;
int dp[200][200];
int f[200],n,p,num[200],flag[200];
void add_edge(int from,int to)
{
e[cnt].to=to;
e[cnt].next=head[from];
head[from]=cnt++;
}
int dfs(int v,int u)
{
int res=1;
for(int i=head[v];i!=-1;i=e[i].next)
{
int to=e[i].to;
res+=dfs(to,v);
for(int j=res;j>0;j--)
{
for(int k=1;k<j;k++)
{
dp[v][j]=MIN(dp[v][j],dp[v][j-k]+dp[to][k]-1);
}
}
}
return res;
}
int main()
{
scanf("%d%d",&n,&p);
cnt=0;
memset(head,-1,sizeof(head));
memset(num,0,sizeof(num));
memset(flag,0,sizeof(flag));
memset(dp,0x3f,sizeof(dp));
for(int i=1;i<n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
add_edge(a,b);
num[a]++;
flag[b]=1;
}
for(int i=1;i<=n;i++)
{
dp[i][1]=num[i];
}
int ans;
for(int i=1;i<=n;i++)
{
if(!flag[i])
{
dfs(i,-1);
ans=dp[i][p];
break;
}
}
for(int i=1;i<=n;i++)
ans=MIN(ans,dp[i][p]+1);
printf("%d\n",ans);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  动态规划 poj