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); }
相关文章推荐
- 智力题:25个人,每5个人一个跑道,最少经过几次比赛,得到前三名
- poj 1947 树形dp(得到含P个节点联通块的最小切边数)
- 输出最少经过几步可以得到回文数
- poj1159 —— 一个字符串,求最少插入几个字符可以组成回文
- poj 1947 Rebuilding Roads(树形DP)
- Apache+php,我想在某个特定的时间(比如每个月底)执行某段代码(某个函数),可以办得到
- POJ 1947 Rebuilding Roads 树形dp
- POJ_1947 Rebuilding Roads --树形DP
- POJ-1947 Rebuilding Roads 树形DP+分组背包
- POJ 1947 树形背包
- poj 1947 树形dp
- POJ-1947 Rebuilding Roads 树形DP
- poj 1947 树形DP+01背包
- poj 1947 Rebuilding Roads 树形动态规划,由左向右合并子树
- poj 2486 树形DP 子树合并
- poj 1947 简单树形dp building roads
- POJ 1947 Rebuilding Roads 树形DP
- POJ 3278第一道BFS,此题刚开始做是纠结了很久,毕竟是第一道要用到队列又赶紧把队列看了一遍,经过几次WA后左后总算AC了
- poj 1947 Rebuilding Roads(树形dp)
- jsp、js限制本地上传图片大小、类型(js经过测试,项目中可以使用)