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)表示两种颜色分别染的 ...
随机推荐
- python中locals和globals函数
参考:http://www.cnblogs.com/wanxsb/archive/2013/05/07/3064783.html Python有两个内置的函数,locals() 和globals(), ...
- 《深入浅出 Java Concurrency》—并发容器 ConcurrentMap
(转自:http://blog.csdn.net/fg2006/article/details/6404226) 在JDK 1.4以下只有Vector和Hashtable是线程安全的集合(也称并发容器 ...
- online community
online community spectrum https://spectrum.chat/xgqfrms https://community.xgqfrms.xyz/ https://spect ...
- 【Python】Python中子类怎样调用父类方法
python中类的初始化方法是__init__(),因此父类子类的初始化方法都是这个,如果子类不实现这个函数,初始化时调用父类的初始化函数,如果子类实现这个函数,就覆盖了父类的这个函数,既然继承父类, ...
- node和gulp实现前端工程自动化(附:gulp常用插件)
/** * 1. LESS编译 压缩 合并 * 2. JS合并 压缩 混淆 * 3. img复制 * 4. html压缩 */ // 在gulpfile中先载入gulp包,因为这个包提供了一些APIv ...
- 51nod 1967路径定向(欧拉回路)
题目大意:给出一个图,安排边的方向,使得入度等于出度的点数最多,并给出方案. 首先假设是个无向图,不妨认定偶点必定可以满足条件 我们还会发现,奇点的个数必定是偶数个 那么如果把奇点两两用辅助边连起来, ...
- [洛谷P3376]【模板】网络最大流(ISAP)
C++ Code:(ISAP) #include <cstdio> #include <cstring> #define maxn 1210 #define maxm 1200 ...
- 洛谷 P2893 [USACO08FEB]修路Making the Grade 解题报告
P2893 [USACO08FEB]修路Making the Grade 题目描述 A straight dirt road connects two fields on FJ's farm, but ...
- 莫比乌斯反演题表II
bzoj3994:[SDOI2015]约数个数和 **很好推+有个小结论bzoj3309:DZY Loves Math ***很好推+线筛某函数/卡常bzoj4816:[Sdoi2017]数字表格 * ...
- Vue获取DOM元素样式 && 样式更改
在 vue 中用 document 获取 dom 节点进行节点样式更改的时候有可能会出现 'style' is not definde的错误, 这时候可以在 mounted 里用 $refs 来获取样 ...