题干:

The cows have reconstructed Farmer John's farm, with its N barns (1 <= N <= 150, number 1..N) after the terrible earthquake last May. The cows didn't have time to rebuild any extra roads, so now there is exactly one way to get from any given barn to any other barn. Thus, the farm transportation system can be represented as a tree.

Farmer John wants to know how much damage another earthquake could do. He wants to know the minimum number of roads whose destruction would isolate a subtree of exactly P (1 <= P <= N) barns from the rest of the barns.

Input

* Line 1: Two integers, N and P

* Lines 2..N: N-1 lines, each with two integers I and J. Node I is node J's parent in the tree of roads.

Output

A single line containing the integer that is the minimum number of roads that need to be destroyed for a subtree of P nodes to be isolated.

Sample Input

11 6
1 2
1 3
1 4
1 5
2 6
2 7
2 8
4 9
4 10
4 11

Sample Output

2

Hint

[A subtree with nodes (1, 2, 3, 6, 7, 8) will become isolated if roads 1-4 and 1-5 are destroyed.]

题目大意:

将一棵n个节点的有根树,删掉一些边变成恰有m个节点的新树。求最少需要去掉几条边。

解题报告:

dp[i][j]代表,以 i 为根节点,砍掉 j 个子节点的子树,所要删除的边的个数

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 555;
const int INF = 0x3f3f3f3f;
int dp[MAX][MAX];//以i节点为根节点,切掉了j个节点的最小刀数
int n,p;
vector<int> vv[MAX];
void dfs(int cur,int rt) {int up = vv[cur].size();for(int i = 0; i<up; i++) {int v = vv[cur][i];if(v == rt) continue;dfs(v,cur);for(int j = p; j>1; j--) {for(int k = 1 ; k < j ; ++k)//划分成子树下的节点和本身的节点数dp[cur][j] = min(dp[cur][j] , dp[v][k]+dp[cur][j-k]-2);}}
}
int main()
{cin>>n>>p;for(int a,b,i = 1; i<=n-1; i++) {scanf("%d%d",&a,&b);vv[a].pb(b);vv[b].pb(a);}memset(dp,INF,sizeof dp);for(int i = 1; i<=n; i++) dp[i][1] = vv[i].size();dfs(1,-1);int ans = INF;for(int i=1;i<=n;i++) ans=min(dp[i][p],ans);cout <<ans <<endl;return 0 ;
} 

AC代码2:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,p,k,head[160],rd[160],dp[160][160],siz[160],ans=0x3f3f3f;
struct edge {int to,next;} ed[330];
void adde(int u,int v){ed[++k].to=v;ed[k].next=head[u];head[u]=k;}void dfs1(int u,int fa)
{siz[u]++;for(int i=head[u];i;i=ed[i].next){int v=ed[i].to;if(v==fa) continue;dfs1(v,u);siz[u]+=siz[v];}dp[u][siz[u]]=1;//如果切掉整棵子树,只需切掉与父节点的连边 dp[u][0]=0;//不切
}void dfs2(int u,int fa)
{for(int i=head[u];i;i=ed[i].next){int v=ed[i].to;if(v==fa) continue;dfs2(v,u);for(int j=siz[u]-1;j;j--)//我切多少 for(int k=0;k<=j;k++)//我的儿子切多少 dp[u][j]=min(dp[u][j],dp[u][j-k]+dp[v][k]);//我切j个节点切的最少边数=min 我切j-k个节点的最少边数+我的儿子切k个节点的最少边数 }if(siz[u]-p>=0)//有那么多节点 ans=min(ans,dp[u][siz[u]-p]+dp[u][siz[u]]);//min 切掉siz[u]-p个节点(剩P个节点)的最少边数+分开我与父亲的边
}int main()
{scanf("%d%d",&n,&p);memset(dp,0x3f3f3f,sizeof(dp));//初始化为最大值 for(int i=1;i<=n-1;i++){int u,v;scanf("%d%d",&u,&v);adde(u,v);adde(v,u);}dfs1(1,1);//求siz数组 & 初始化 dp[1][siz[1]]=0;//根节点不需要与父节点分开  (没有父亲。。。) dfs2(1,1);//树形dp printf("%d",ans);return 0;
}

【POJ - 1947】Rebuilding Roads (树形dp,背包问题,树形背包dp)相关推荐

  1. POJ 1947 Rebuilding Roads (树dp + 背包思想)

    题目链接:http://poj.org/problem?id=1947 一共有n个节点,要求减去最少的边,行号剩下p个节点.问你去掉的最少边数. dp[u][j]表示u为子树根,且得到j个节点最少减去 ...

  2. 51NOD 2072 装箱问题 背包问题 01 背包 DP 动态规划

    有一个箱子容量为 V(正整数,0<=V<=20000),同时有 n 个物品(0<n<=30),每个物品有一个体积(正整数). 现在在 n 个物品中,任取若干个装入箱内,使得箱子 ...

  3. (背包dp) 背包N讲

    文章目录 前言 相关练习题 模板题 01背包 完全背包 多重背包 小数据范围 (可朴素暴力) 中等数据范围 (二进制优化) 大数据范围 (单调队列优化) 混合背包 二维费用背包 分组背包 有依赖的背包 ...

  4. poj 1947(树形dp+背包问题)

    题大意是:给你一棵节点为n的树,问至少砍几刀可以孤立出一棵节点为m的子树. 解题思路:这题很容易想到状态dp[i][j]表示以i节点为根,节点总数为j的子树最少需要切几刀.但是这个状态方程确实很难想, ...

  5. Codeforces 835 F Roads in the Kingdom(树形dp)

    F. Roads in the Kingdom(树形dp) 题意: 给一张n个点n条边的无向带权图 定义不便利度为所有点对最短距离中的最大值 求出删一条边之后,保证图还连通时不便利度的最小值 $n & ...

  6. *【POJ - 3659】Cell Phone Network (树形dp,最小支配集)

    题干: Farmer John has decided to give each of his cows a cell phone in hopes to encourage their social ...

  7. 【POJ - 3342】Party at Hali-Bula(树形dp,最大独立集,是否有唯一解)

    题干: Dear Contestant, I'm going to have a party at my villa at Hali-Bula to celebrate my retirement f ...

  8. 【bzoj4007】[JLOI2015]战争调度 暴力+树形背包dp

    题目描述 给你一棵 $n$ 层的完全二叉树,每个节点可以染黑白两种颜色.对于每个叶子节点及其某个祖先节点,如果它们均为黑色则有一个贡献值,如果均为白色则有另一个贡献值.要求黑色的叶子节点数目不超过 $ ...

  9. 【bzoj4753】[Jsoi2016]最佳团体 分数规划+树形背包dp

    题目描述 JSOI信息学代表队一共有N名候选人,这些候选人从1到N编号.方便起见,JYY的编号是0号.每个候选人都由一位编号比他小的候选人Ri推荐.如果Ri=0则说明这个候选人是JYY自己看上的.为了 ...

最新文章

  1. python中filenotfounderror_Python3 报错 FileNotFoundError: [WinError 2]
  2. linux之间文件传输scp
  3. Known Notation 39届亚洲赛牡丹江站K题
  4. u盘安装linux18.04.3遇到的坑
  5. 第二轮冲次会议第七次
  6. 重新审视自己和自己的目标
  7. http://w3cschool.codecloud.net/python/python-object.html?ref=myread
  8. python 协程池gevent.pool_进程池\线程池,协程,gevent
  9. C语言union关键字
  10. (python)7-6 sdut-数制转换
  11. Python画等高线以及标注
  12. 超分辨率技术如何发展?这6篇ECCV 18论文带你一次尽览
  13. Android 属性动画实现一个简单的PopupWindow
  14. Open XML应用安全(3)隐藏数据
  15. 域名策略服务器未运行,谈一谈网站突然无法访问的原因及解决策略
  16. 7-6 程序员买西瓜 (5分)
  17. Element_Table的单元格合并
  18. 数字电路74161(MN)
  19. 民俗杂事丨“大力丸”是壮阳药吗?
  20. STM32入门之LCD1602驱动

热门文章

  1. 996. Number of Squareful Arrays
  2. 动态规划——双11既可以薅羊毛还能花钱最少
  3. 深度学习第三次课-梯度下降与反向传播
  4. linux 进入一个中文乱码的目录的方法
  5. CodeForces 841B (B) 博弈
  6. HDU - 5441 Travel 离线处理+并查集
  7. 计算机工程与应用单像素成像,2011计算机工程与应用基于压缩感知理论的单像素成像系统研究_白凌云.pdf...
  8. mysql提供了表示日期和时间的数据类型_MySQL数据类型 - 日期和时间类型(1)
  9. python中restful接口开发实例_Python RESTful接口开发02
  10. 最长非降子序列(动态规划dp dynamic programming)