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)表示两种颜色分别染的 ...
随机推荐
- 解决ecplise安装mybatipse插件时报找不到jar包的错
在安装mybatipse插件的时候一直报这个错,脑袋疼,在网上搜了半天也没有结果,最后摸索了半天解决了,这里先贴一张图 1.先找到eclipse的安装目录,然后把相应的jar包拷到plugins里去, ...
- vuex中获取的数据使用v-model绑定出问题
get selectedProp() { return this.$store.state.selectedProp; } 获取的数据selectedProp直接绑定在表单元素上会有错,因为不能直接对 ...
- python practive
定义新的操作指令,并将其组合到一起以便能够做一些有意义的事情,这就是编程工作的核心和灵魂. 计算型思维: 1,强调概念化,而非程序化.计算机科学不是计算机程序.像计算机科学家一样的思考,不只是说要编程 ...
- qemu的device参数解释 包括socket的一些知识
前面一片是driver,是把这个新的设备“插入到虚机中”,device 是准备驱动了.device 都是和设备配合使用的.要怎么去驱动一个设备,包括使用的驱动函数是啥,device后面的函数根据驱动的 ...
- 关于JS中array对象的push( )
push()的参数传的是指针,不是值. var arr = new Array(); var item = 5; arr.push(item); var item = 6; 运行以上代码,arr中的元 ...
- 【BZOJ 3551】[ONTAK2010] Peaks加强版 Kruskal重构树+树上倍增+主席树
这题真刺激...... I.关于Kruskal重构树,我只能开门了,不过补充一下那玩意还是一棵满二叉树.(看一下内容之前请先进门坐一坐) II.原来只是用树上倍增求Lca,但其实树上倍增是一种方法,L ...
- pmap用法小计
By francis_hao Aug 4,2017 pmap-报告进程的内存映射. 概要 pmap [options] pid [...] 描述 pmap命令用来报告一个或多个进程的 ...
- spring @Profile的运用示例
@Profile的作用是把一些meta-data进行分类,分成Active和InActive这两种状态,然后你可以选择在active 和在Inactive这两种状态 下配置bean, 在Inactiv ...
- 数据仓库3级范式(3NF)基础
一.引言 最近在整理理大数据模式下的数据仓库数据模型,资料来自互联网和读过的数据仓库理论和实践相关. 二.3NF (1)1NF-无重复的列 数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个 ...
- hihoCoder 1527 快速乘法
#include<bits/stdc++.h> using namespace std; ; char a[N]; int main() { scanf(); ); ,r = n; ') ...