poj 1947(树形DP+背包)
| Time Limit: 1000MS | Memory Limit: 30000K | |
| Total Submissions: 10663 | Accepted: 4891 |
Description
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
* 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
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个结点n-1条边的树中取m个点所需要的最少切割数.
分析:dp[u][i]代表以u为根节点的子树要得到i个结点的子树需要最少的切割数 如果考虑u的子树v,如果我们在除去v之外的父亲树中取k个点,那么在子树中取i-k个点
dp[u][i] = min(dp[u][k]+dp[v][i-k]) ........1
如果不考虑v,那么我们只需要一刀将子树k与父亲分开即可dp[u][i] = dp[u][i]+1; ..........2
综上述:dp[u][i] = min(1,2)
我们在考虑u的时候,等于u是一个容量为m(m为背包容量)的背包,在子树中取m个结点组成,每个点只有取或不取一个,所以可以将其看成01背包。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <algorithm>
#define N 155
using namespace std; int head[N];
struct Edge{
int u,v,next;
}edge[N]; int indegree[N];
void addEdge(int u,int v,int &k){
edge[k].u = u,edge[k].v = v;
edge[k].next = head[u],head[u]=k++;
}
int n,m;
int dp[N][N];///dp[u][i]代表以u为根节点的子树要得到i个结点的子树需要最少的切割数
/// 如果考虑u的子树v,如果我们在父亲树中取k个点,那么在子树中取i-k个点
///dp[u][i] = min(dp[u][k],dp[v][i-k])
///如果不考虑v,那么我们只需要一刀将子树k与父亲分开即可 dp[u][i] = dp[u][i]+1;
///综上述:dp[u][i] = min(min(dp[u][k],dp[v][i-k]),dp[u][i]+1)
///我们在考虑u的时候,等于u是一个容量为m(m为背包容量)的背包,在子树中取m个结点组成,每个点只有取或不取且最多取一次,所以
void dfs(int u){
for(int i=;i<=m;i++) dp[u][i]=;
dp[u][]=; ///初始化只取自己一个点
for(int k = head[u];k!=-;k=edge[k].next){
int v = edge[k].v;
dfs(v);
for(int j=m;j>=;j--){ ///逆序枚举
dp[u][j]+=; ///不取子树时
for(int k=;k<j;k++){ ///父亲树上取得点
int t = j-k; ///子树上取的点
dp[u][j] = min(dp[u][k]+dp[v][t],dp[u][j]);
}
}
}
}
int main()
{ while(scanf("%d%d",&n,&m)!=EOF){
memset(indegree,,sizeof(indegree));
memset(head,-,sizeof(head));
int tot = ;
int u,v;
for(int i=;i<n;i++){
scanf("%d%d",&u,&v);
addEdge(u,v,tot);
indegree[v]++;
}
int root ;
for(int i=;i<=n;i++) if(indegree[i]==){root = i;break;}
//printf("%d\n",root);
dfs(root);
int ans = dp[root][m];
for(int i=;i<=n;i++){ ///加一是因为父亲结点和它之间还有边连着
if(dp[i][m]+<ans) ans = dp[i][m]+;
}
printf("%d\n",ans);
}
return ;
}
poj 1947(树形DP+背包)的更多相关文章
- POJ 1155 (树形DP+背包+优化)
题目链接: http://poj.org/problem?id=1155 题目大意:电视台转播节目.对于每个根,其子结点可能是用户,也可能是中转站.但是用户肯定是叶子结点.传到中转站或是用户都要花钱, ...
- poj 1947 树形dp
思路:dp[i][j]表示,以i节点为根,删去j个节点最少要断几条边. 那么dp[u][j]=min(dp[u][j],dp[v][k]+dp[u][j-k]);//选取最优状态 dp[u][j]=m ...
- Fire (poj 2152 树形dp)
Fire (poj 2152 树形dp) 给定一棵n个结点的树(1<n<=1000).现在要选择某些点,使得整棵树都被覆盖到.当选择第i个点的时候,可以覆盖和它距离在d[i]之内的结点,同 ...
- URAL_1018 Binary Apple Tree 树形DP+背包
这个题目给定一棵树,以及树的每个树枝的苹果数量,要求在保留K个树枝的情况下最多能保留多少个苹果 一看就觉得是个树形DP,然后想出 dp[i][j]来表示第i个节点保留j个树枝的最大苹果数,但是在树形过 ...
- hdu1561 The more, The Better (树形dp+背包)
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1561 思路:树形dp+01背包 //看注释可以懂 用vector建树更简单. 代码: #i ...
- poj 1463(树形dp)
题目链接:http://poj.org/problem?id=1463 思路:简单树形dp,如果不选父亲节点,则他的所有的儿子节点都必须选,如果选择了父亲节点,则儿子节点可选,可不选,取较小者. #i ...
- poj 2486( 树形dp)
题目链接:http://poj.org/problem?id=2486 思路:经典的树形dp,想了好久的状态转移.dp[i][j][0]表示从i出发走了j步最后没有回到i,dp[i][j][1]表示从 ...
- poj 3140(树形dp)
题目链接:http://poj.org/problem?id=3140 思路:简单树形dp题,dp[u]表示以u为根的子树的人数和. #include<iostream> #include ...
- codeforces 212E IT Restaurants(树形dp+背包思想)
题目链接:http://codeforces.com/problemset/problem/212/E 题目大意:给你一个无向树,现在用两种颜色去给这颗树上的节点染色.用(a,b)表示两种颜色分别染的 ...
随机推荐
- Mac上基于hexo+GitHub搭建个人博客(一)
原文地址: http://fanjiajia.cn/2018/11/23/Mac%E4%B8%8A%E5%9F%BA%E4%BA%8Ehexo+GitHub%E6%90%AD%E5%BB%BA%E4% ...
- java课程设计——2048
1.团队介绍 2.项目git地址 [https://gitee.com/SMTwula/java036.git] 3.项目git提交记录截图 沈梦婷 田亚琴 4.项目功能架构图与主要功能流程图 5.项 ...
- CSS设计指南之伪类
伪类这个叫法源自它们与类相似,但实际上并没有类会附加到标记中的标签上.伪类分两种. UI伪类会在HTML元素处于某个状态时(比如鼠标指针位于链接上),为该元素应用CSS样式. 结构化伪类会在标记中存在 ...
- JavaScript constructor 属性详解
对象的constructor属性用于返回创建该对象的函数,也就是我们常说的构造函数. 在JavaScript中,每个具有原型的对象都会自动获得constructor属性.除了arguments.Enu ...
- [洛谷P2032]扫描
题目大意:有一串数,有一个长度为k的木板,求木板每次移动后覆盖的最大值 题解:单调队列 C++ Code: #include<cstdio> using namespace std; co ...
- BZOJ2120 数颜色 【带修改莫队】
2120: 数颜色 Time Limit: 6 Sec Memory Limit: 259 MB Submit: 6579 Solved: 2625 [Submit][Status][Discus ...
- 《软件调试的艺术》学习笔记——GDB使用技巧摘要
<软件调试的艺术>学习笔记——GDB使用技巧摘要 <软件调试的艺术>,因为名是The Art of Debugging with GDB, DDD, and Eclipse. ...
- 如何使用Photoshop批量扫描保存文档
以笔主手头上的Canon LIDE 100为例 先安装好扫描仪驱动程序,可使用自带驱动光盘或驱动精灵等程序完成. 打开Photoshop程序,以CS5为例,找到扫描仪入口: 点开高级模式进行配置,笔主 ...
- 洛谷P1273 有线电视网 (树上分组背包)
洛谷P1273 有线电视网 题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的内部节 ...
- [bzoj 2733]启发式合并权值线段树
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2733 平衡树待学习.从一个博客学到了合并权值线段树的姿势:http://blog.csdn ...