DP Intro - poj 1947 Rebuilding Roads(树形DP)
版权声明:本文为博主原创文章,未经博主允许不得转载。
|
Rebuilding Roads
Description The cows have reconstructed Farmer John's farm, with its N barns (1 <= N <= 150, number 1..N) after the terrible earthquake last May. The cows didn't have time to rebuild any extra roads, so now there is exactly one way to get from any given barn to any other barn. Thus, the farm transportation system can be represented as a tree.
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 * Line 1: Two integers, N and P
* 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 A 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 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.]
Source |
题意:
给你一棵树,求最少剪掉几条边使能够得到一个p个节点的树。
思路:
用dp[i][j]代表以i为根的子树要变成j个节点需要剪掉的边数。
考虑子节点的时候不用考虑它与父节点的那条边,就当不存在,那么最后求的的最小边数加1就行了。
考虑一个节点时,有两种选择,要么剪掉跟子节点相连的边,则dp[i][j] = dp[i][j]+1;
要么不剪掉,则dp[i][j] = max(dp[i][j], dp[i][k]+dp[son][j-k]);
然后随便以一条边dfs求解就行了。
为什么可以这样求解呢。
对于树上的一个节点。要么在待求解子树中。要么不在。在的话即dp[i][p]中。不然的话就肯定在其它子树上了。
详细见代码:
- #include <iostream>
- #include<stdio.h>
- #include<string.h>
- using namespace std;
- const int maxn=250;
- const int INF=0x3f3f3f3f;
- struct node
- {
- int v;
- node *next;
- } edge[maxn<<1],*head[maxn];
- int n,m,cnt,dp[maxn][maxn];
- void adde(int u,int v)
- {
- edge[cnt].v=v;
- edge[cnt].next=head[u];
- head[u]=&edge[cnt++];
- }
- void dfs(int fa,int u)
- {
- int i,j,v,mm=INF;
- node *p;
- dp[u][1]=0;
- for(p=head[u];p!=NULL;p=p->next)
- {
- v=p->v;
- if(v==fa)
- continue;
- dfs(u,v);
- for(i=m;i>=1;i--)//01背包。从大到小装
- {
- mm=dp[u][i]+1;//不要该子树.
- for(j=1;j<i;j++)//要该子树
- mm=min(mm,dp[u][j]+dp[v][i-j]);
- dp[u][i]=mm;
- }
- }
- }
- int main()
- {
- int i,u,v,ans;
- while(~scanf("%d%d",&n,&m))
- {
- cnt=0;
- memset(head,0,sizeof head);
- memset(dp,0x3f,sizeof dp);
- for(i=1;i<n;i++)
- {
- scanf("%d%d",&u,&v);
- adde(u,v);
- adde(v,u);
- }
- dfs(1,1);
- ans=dp[1][m];
- for(i=1;i<=n;i++)
- ans=min(ans,dp[i][m]+1);//加1是因为根转移了
- printf("%d\n",ans);
- }
- return 0;
- }
DP Intro - poj 1947 Rebuilding Roads(树形DP)的更多相关文章
- 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 ...
- DP Intro - poj 1947 Rebuilding Roads
算法: dp[i][j]表示以i为根的子树要变成有j个节点的状态需要减掉的边数. 考虑状态转移的时候不考虑i的父亲节点,就当不存在.最后统计最少减去边数的 时候+1. 考虑一个节点时,有两种选择,要么 ...
- 树形dp(poj 1947 Rebuilding Roads )
题意: 有n个点组成一棵树,问至少要删除多少条边才能获得一棵有p个结点的子树? 思路: 设dp[i][k]为以i为根,生成节点数为k的子树,所需剪掉的边数. dp[i][1] = total(i.so ...
- 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
Rebuilding Roads Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 10653 Accepted: 4884 Des ...
- POJ 1947 Rebuilding Roads (树dp + 背包思想)
题目链接:http://poj.org/problem?id=1947 一共有n个节点,要求减去最少的边,行号剩下p个节点.问你去掉的最少边数. dp[u][j]表示u为子树根,且得到j个节点最少减去 ...
- POJ1947 - Rebuilding Roads(树形DP)
题目大意 给定一棵n个结点的树,问最少需要删除多少条边使得某棵子树的结点个数为p 题解 很经典的树形DP~~~直接上方程吧 dp[u][j]=min(dp[u][j],dp[u][j-k]+dp[v] ...
- POJ 1947 Rebuilding Roads
树形DP..... Rebuilding Roads Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 8188 Accepted: ...
随机推荐
- JS 观察者模式
Events = function() { var listen, log, obj, one, remove, trigger, __this; obj = {}; __this = this; l ...
- 引用数据类型(类)和ArrayList
引用数据类型(类) 类的类型为两种: 第一种,Java为我们提供好的类,如Scanner类,Scanner类等,这些已存在的类中包含了很多的方法与属性,可供我们使用. 第二种,我们自己创建的类,按照类 ...
- 多线程的那点儿事(之windows锁)
在windows系统中,系统本身为我们提供了很多锁.通过这些锁的使用,一方面可以加强我们对锁的认识,另外一方面可以提高代码的性能和健壮性.常用的锁以下四种:临界区,互斥量,信号量,event. (1) ...
- NSArray去除重复元素
直接上代码吧! 1.可以创建一个新的数组,对需要去除重复的数组进行遍历,如果新数组不包含就数组,那么添加元素,如果包含就不添加. NSMutableArray *array = [NSMutableA ...
- 浅谈HTTPS以及Fiddler抓取HTTPS协议(摘抄)
一.浅谈HTTPS 我们都知道HTTP并非是安全传输,在HTTPS基础上使用SSL协议进行加密构成的HTTPS协议是相对安全的.目前越来越多的企业选择使用HTTPS协议与用户进行通信,如百度.谷歌等. ...
- [LeetCode 题解]: Triangle
前言 [LeetCode 题解]系列传送门: http://www.cnblogs.com/double-win/category/573499.html 1.题目描述 Given a tr ...
- pycharm注册
1.官方下载专业版,并安装 http://www.jetbrains.com/pycharm/download/#section=windows 2.下载crack激活包 http://idea.la ...
- 40. 组合总和 II leetcode JAVA
题目: 给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的每个数字在每个组合中只能使 ...
- 带你玩转Visual Studio——带你高效开发
VassistX的简单介绍与下载安装 简单介绍 VassistX的全称是Visual Assist X,是whole tomato开发的一个非常好用的插件,可用于VC6.0及Visual Studio ...
- day13学python 协程+事件驱动
协程+事件驱动 协程 (微线程)--用处多,重点 当调度切换时 靠寄存器上下文和栈保存 要使用时再调用(即可不会因io传输数据卡壳 从而耗时无法继续进行)实现并行 优缺点: 优点: 1 无需同线程上下 ...