POJ-1947 Rebuilding Roads (树形DP+分组背包)
题目大意:将一棵n个节点的有根树,删掉一些边变成恰有m个节点的新树。求最少需要去掉几条边。
题目分析:定义状态dp(root,k)表示在以root为根节点的子树中,删掉一些边变成恰有k个节点的新树需要删去的最少边数。对于根节点root的某个儿子son,要么将son及其所有的子节点全部删掉,则dp(root,k)=dp(root,k)+1,只需删除root与son之间的边;要么在son的子树中选出一些边删掉,构造出有j个节点的子树,状态转移方程为dp(root,k)=max(dp(root,k),dp(son,j)+dp(root,k-j))。
代码如下:
# include<iostream>
# include<cstdio>
# include<cstring>
# include<vector>
# include<algorithm>
using namespace std; const int N=155;
const int INF=1000000000; int n,m;
bool flag[N];
int dp[N][N];
vector<int>e[N]; void init()
{
int a,b;
for(int i=1;i<=n;++i){
e[i].clear();
for(int j=0;j<=m;++j)
dp[i][j]=INF;
}
memset(flag,false,sizeof(flag));
for(int i=1;i<n;++i){
scanf("%d%d",&a,&b);
e[a].push_back(b);
flag[b]=true;
}
} void dfs(int u)
{
dp[u][1]=0;
for(int i=0;i<e[u].size();++i){
int v=e[u][i];
dfs(v);
for(int j=m;j>=1;--j){
dp[u][j]+=1;
for(int k=1;k<j;++k){ ///k从1循环到j-1,一定不能从0循环到j
dp[u][j]=min(dp[u][j],dp[v][k]+dp[u][j-k]);
}
}
}
} void solve()
{
int ans=INF;
for(int i=1;i<=n;++i){
if(flag[i]) continue;
dfs(i);
ans=dp[i][m];
break;
}
for(int i=1;i<=n;++i)
ans=min(ans,dp[i][m]+1);
printf("%d\n",ans);
} int main()
{
while(~scanf("%d%d",&n,&m))
{
init();
solve();
}
return 0;
}
POJ-1947 Rebuilding Roads (树形DP+分组背包)的更多相关文章
- DP Intro - poj 1947 Rebuilding Roads(树形DP)
版权声明:本文为博主原创文章,未经博主允许不得转载. Rebuilding Roads Time Limit: 1000MS Memory Limit: 30000K Total Submissi ...
- POJ 1947 Rebuilding Roads 树形DP
Rebuilding Roads Description The cows have reconstructed Farmer John's farm, with its N barns (1 & ...
- POJ 1947 Rebuilding Roads 树形dp 难度:2
Rebuilding Roads Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 9105 Accepted: 4122 ...
- [poj 1947] Rebuilding Roads 树形DP
Rebuilding Roads Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 10653 Accepted: 4884 Des ...
- POJ 1947 Rebuilding Road(树形DP)
Description The cows have reconstructed Farmer John's farm, with its N barns (1 <= N <= 150, n ...
- POJ 1947 Rebuilding Roads (树dp + 背包思想)
题目链接:http://poj.org/problem?id=1947 一共有n个节点,要求减去最少的边,行号剩下p个节点.问你去掉的最少边数. dp[u][j]表示u为子树根,且得到j个节点最少减去 ...
- 树形dp(poj 1947 Rebuilding Roads )
题意: 有n个点组成一棵树,问至少要删除多少条边才能获得一棵有p个结点的子树? 思路: 设dp[i][k]为以i为根,生成节点数为k的子树,所需剪掉的边数. dp[i][1] = total(i.so ...
- POJ 1947 Rebuilding Roads
树形DP..... Rebuilding Roads Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 8188 Accepted: ...
- HDU4003Find Metal Mineral[树形DP 分组背包]
Find Metal Mineral Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Other ...
- HDU-1011 Starship Troopers (树形DP+分组背包)
题目大意:给一棵有根带点权树,并且给出容量.求在不超过容量下的最大权值.前提是选完父节点才能选子节点. 题目分析:树上的分组背包. ps:特判m为0时的情况. 代码如下: # include<i ...
随机推荐
- PowerShell并发控制-命令行参数之四问
传教士问: win下如何 获取进程命令行,及命令行参数? 传教士答: 可以用这个powershell命令(实际上是wmi查询): (get-wmiobject -query "select ...
- main函数参数的使用
int main(int argc, char * argv[]) argc: argument count argv:argument vector 其中, char * argv[] 指针数组 c ...
- C# WebRequestExtensions
https://gist.github.com/abombss/2720757 public static class WebRequestExtensions { public static Htt ...
- CSS网页布局:网站整体居中 转
body{ margin:0 auto; padding:0 auto; text-align:center;} 只设置body属性对ie浏览器有效果,但是对火狐等不起作用 body{ ...
- 技术分享:逆向海盗船k95机械键盘
引文 在几年前我买了一个海盗船 K95 Vengeance机械键盘,键盘有上有背光功能,于是我在考虑是不是可以修改一下.但作者表示购买来的键盘上面没有很多的资料可供利用,需要注意的是,新版的K95与旧 ...
- STL 源码分析《2》----nth_element() 使用与源码分析
Select 问题: 在一个无序的数组中 找到第 n 大的元素. 思路 1: 排序,O(NlgN) 思路 2: 利用快排的 RandomizedPartition(), 平均复杂度是 O(N) 思路 ...
- BZOJ 1486 最小圈
二分答案是显然的,我们需要dfs版spfa判一下负环. 看起来是n^2其实很快. #include<iostream> #include<cstdio> #include< ...
- PHP实现简单计算器
<!--简单的计算器--> <!DOCTYPE html> <html> <head> <title>PHP实现简单计算器</titl ...
- ubuntu系统安装mongodb
安装mongodb sudo apt-get install mongodb ... ... 设置客户端连接 打开文件/etc/mongodb.conf 注意权限 修改 bind_ip=127.0. ...
- Cocos2d-x 3.x项目创建
1.首先打开终端,cd到cocos2d-x-3.2目录下,运行命令./setup.py 2. 首先,打开终端cd到目录/cocos2d-x-3.2/tools/cocos2d-console/bin下 ...