POJ 1947 Rebuilding Roads (树dp + 背包思想)
题目链接:http://poj.org/problem?id=1947
一共有n个节点,要求减去最少的边,行号剩下p个节点。问你去掉的最少边数。
dp[u][j]表示u为子树根,且得到j个节点最少减去的边数。
考虑两种情况,去掉孩子节点v与去不掉。
(1)去掉孩子节点:dp[u][j] = dp[u][j] + 1
(2)不去掉孩子节点:dp[u][j] = min(dp[u][j - k] + dp[v][k])
综上就是dp[u][j] = min(dp[u][j] + 1, min(dp[u][j - k] + dp[v][k]))
//#pragma comment(linker, "/STACK:102400000, 102400000")
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <ctime>
#include <list>
#include <set>
#include <map>
using namespace std;
typedef long long LL;
typedef pair <int, int> P;
const int N = ;
int dp[N][N], n, p, inf = 1e8;
vector <int> edge[N];
//dp[i][j]表示i为子树根,且得到j个节点最少减去的边数。不考虑父节点 void dfs(int u, int par) {
for(int i = ; i <= p; ++i) {
dp[u][i] = inf;
}
dp[u][] = ; //考虑到叶子节点,而非叶子节点在下面的for中会增加
for(int i = ; i < edge[u].size(); ++i) {
int v = edge[u][i];
if(v == par)
continue;
dfs(v, u);
for(int j = p; j >= ; --j) {
//有点背包的思想,正序的话dp[u][j]可能由dp[v][k]转移而来,在下面会被重复转移。倒序的话保证转移一次。
int temp = dp[u][j] + ; //去掉v子树
for(int k = ; k < j; ++k) {
temp = min(dp[u][j - k] + dp[v][k], temp);
}
dp[u][j] = temp; //最优 跟最短路思想类似
}
}
} int main()
{
int u, v;
while(~scanf("%d %d", &n, &p)) {
for(int i = ; i <= n; ++i) {
edge[i].clear();
}
for(int i = ; i < n; ++i) {
scanf("%d %d", &u, &v);
edge[u].push_back(v);
edge[v].push_back(u);
}
dfs(, -);
int res = dp[][p]; //根节点没有父亲 不需要+1
for(int i = ; i <= n; ++i) {
res = min(dp[i][p] + , res); //其他节点有父节点 去除的话所以+1
}
printf("%d\n", res);
}
return ;
}
这题感觉好难想,人笨没办法
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(泛化背包转移)..
dp[x][y]表示以x为根的子树要变成有y个点..最少需要减去的边树... 最终ans=max(dp[i][P]+t) < i=(1,n) , t = i是否为整棵树的根 > 更新的时 ...
- [poj 1947] Rebuilding Roads 树形DP
Rebuilding Roads Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 10653 Accepted: 4884 Des ...
- POJ 1947 Rebuilding Roads
树形DP..... Rebuilding Roads Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 8188 Accepted: ...
- 树形dp(poj 1947 Rebuilding Roads )
题意: 有n个点组成一棵树,问至少要删除多少条边才能获得一棵有p个结点的子树? 思路: 设dp[i][k]为以i为根,生成节点数为k的子树,所需剪掉的边数. dp[i][1] = total(i.so ...
- POJ 1947 Rebuilding Roads(树形DP)
题目链接 题意 : 给你一棵树,问你至少断掉几条边能够得到有p个点的子树. 思路 : dp[i][j]代表的是以i为根的子树有j个节点.dp[u][i] = dp[u][j]+dp[son][i-j] ...
- POJ 1947 Rebuilding Roads (树形DP)
题意:给一棵树,在树中删除一些边,使得有一个连通块刚好为p个节点,问最少需要删除多少条边? 思路: 因为任一条边都可能需要被删除,独立出来的具有p个节点的连通块可能在任意一处地方.先从根开始DFS,然 ...
随机推荐
- wordpress plugins collection
1/ simple page ordering 4.8星 wordpress的plugins唯一的好处就是命名简单易懂,这款插件从名称就可以看出来,用来对page页面排序的.只需要在后台page中拖拽 ...
- 20160122.CCPP详解体系(0001天)
程序片段(01):Hello.c 内容概要:HelloWorld //01.#include表示包含的作用: // (1).<>:表示只在系统目录之下进行查找 // (2)."& ...
- django - raw sql - 注意点!
现在的自己已经不怕mysql,已经熟悉了sql “搜索优化专家有时候都无法顾全所有,更何况ORM” 两种方法执行 sql原生语句 tablename.objects.raw() - 这样的语句,只能执 ...
- 并行编译 Xoreax IncrediBuild
好东西... http://pan.baidu.com/s/1BtZ4s
- Cython:基础教程(1) 语法
1 变量定义 http://docs.cython.org/src/reference/language_basics.html http://blog.csdn.net/i2cbus/article ...
- The Robust Fuzzy C-means
摘要: 基于FCM的在图像处理方面对噪声敏感的不足,本文通过引入空间模型建立空间模糊C均值聚类提高算法的鲁棒性,在此基础上,结合抑制式对算法进一步优化.最后,给图像加不同程度的噪声,通过MATLAB编 ...
- Android 适配多种ROM的快捷方式
快捷方式 应该来说 很多人都做过,我们就来看一下基本的快捷方式 是怎么实现的,会有什么问题? 首先 肯定要获取权限: <!-- 添加快捷方式 --> <uses-permission ...
- 可以Ping通和DNS解析,但打不开网页的解决办法
一. 网络故障表现为: 1.Ping地址正常,能ping通任何本来就可以ping通地址,如网关.域名. 2.能DNS解析域名. 3.无法打开网页,感觉是网页打开的一瞬间就显示无网络连接. 4.只需要连 ...
- PHP遍历数组
foreach PHP代码: <?php $url = array( '新浪' =>'www.sina.com' , '雅虎' =>'www ...
- makefile实例(2)-多个文件实例
1,源文件依赖关系 defs.h command.h buffer.h main.cpp * util.cpp * kde.cpp * * command.cpp * * display.cpp * ...