版权声明:本文为博主原创文章,未经博主允许不得转载。

Rebuilding Roads
Time Limit: 1000MS   Memory Limit: 30000K
Total Submissions: 8227   Accepted: 3672

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
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.] 

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]中。不然的话就肯定在其它子树上了。

详细见代码:

  1. #include <iostream>
  2. #include<stdio.h>
  3. #include<string.h>
  4. using namespace std;
  5. const int maxn=250;
  6. const int INF=0x3f3f3f3f;
  7. struct node
  8. {
  9. int v;
  10. node *next;
  11. } edge[maxn<<1],*head[maxn];
  12. int n,m,cnt,dp[maxn][maxn];
  13. void adde(int u,int v)
  14. {
  15. edge[cnt].v=v;
  16. edge[cnt].next=head[u];
  17. head[u]=&edge[cnt++];
  18. }
  19. void dfs(int fa,int u)
  20. {
  21. int i,j,v,mm=INF;
  22. node *p;
  23. dp[u][1]=0;
  24. for(p=head[u];p!=NULL;p=p->next)
  25. {
  26. v=p->v;
  27. if(v==fa)
  28. continue;
  29. dfs(u,v);
  30. for(i=m;i>=1;i--)//01背包。从大到小装
  31. {
  32. mm=dp[u][i]+1;//不要该子树.
  33. for(j=1;j<i;j++)//要该子树
  34. mm=min(mm,dp[u][j]+dp[v][i-j]);
  35. dp[u][i]=mm;
  36. }
  37. }
  38. }
  39. int main()
  40. {
  41. int i,u,v,ans;
  42. while(~scanf("%d%d",&n,&m))
  43. {
  44. cnt=0;
  45. memset(head,0,sizeof head);
  46. memset(dp,0x3f,sizeof dp);
  47. for(i=1;i<n;i++)
  48. {
  49. scanf("%d%d",&u,&v);
  50. adde(u,v);
  51. adde(v,u);
  52. }
  53. dfs(1,1);
  54. ans=dp[1][m];
  55. for(i=1;i<=n;i++)
  56. ans=min(ans,dp[i][m]+1);//加1是因为根转移了
  57. printf("%d\n",ans);
  58. }
  59. return 0;
  60. }

DP Intro - poj 1947 Rebuilding Roads(树形DP)的更多相关文章

  1. POJ 1947 Rebuilding Roads 树形DP

    Rebuilding Roads   Description The cows have reconstructed Farmer John's farm, with its N barns (1 & ...

  2. POJ 1947 Rebuilding Roads 树形dp 难度:2

    Rebuilding Roads Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 9105   Accepted: 4122 ...

  3. DP Intro - poj 1947 Rebuilding Roads

    算法: dp[i][j]表示以i为根的子树要变成有j个节点的状态需要减掉的边数. 考虑状态转移的时候不考虑i的父亲节点,就当不存在.最后统计最少减去边数的 时候+1. 考虑一个节点时,有两种选择,要么 ...

  4. 树形dp(poj 1947 Rebuilding Roads )

    题意: 有n个点组成一棵树,问至少要删除多少条边才能获得一棵有p个结点的子树? 思路: 设dp[i][k]为以i为根,生成节点数为k的子树,所需剪掉的边数. dp[i][1] = total(i.so ...

  5. POJ 1947 Rebuilding Road(树形DP)

    Description The cows have reconstructed Farmer John's farm, with its N barns (1 <= N <= 150, n ...

  6. [poj 1947] Rebuilding Roads 树形DP

    Rebuilding Roads Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 10653 Accepted: 4884 Des ...

  7. POJ 1947 Rebuilding Roads (树dp + 背包思想)

    题目链接:http://poj.org/problem?id=1947 一共有n个节点,要求减去最少的边,行号剩下p个节点.问你去掉的最少边数. dp[u][j]表示u为子树根,且得到j个节点最少减去 ...

  8. POJ1947 - Rebuilding Roads(树形DP)

    题目大意 给定一棵n个结点的树,问最少需要删除多少条边使得某棵子树的结点个数为p 题解 很经典的树形DP~~~直接上方程吧 dp[u][j]=min(dp[u][j],dp[u][j-k]+dp[v] ...

  9. POJ 1947 Rebuilding Roads

    树形DP..... Rebuilding Roads Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 8188 Accepted: ...

随机推荐

  1. 等等,你可能误解nodejs了–通俗的概括nodejs的真相

    最近刚把产品从cpp平台迁移到nodejs平台了.  很多以前关于nodejs的观念被颠覆了. 这里分享出来, 欢迎大家批评指正. "nodejs是做服务器端开发的, 它一定和web相关,几 ...

  2. python下使用tesserocr遇到的一些坑

    我是在win7 64位系统下用的. 首先是安装tesseract,这个可以去官网下载,我使用的是3.05.1,安装时使用默认安装路径就行了,下载语言包速度很慢很慢,需要等 接下来就是安装tessero ...

  3. [NetCore学习记录]第一章.使用netcore撸个简单的增删改查

    1.引言 2.解决方案各部分介绍图 3.添加数据模型 4.添加数据库上下文 5.修改配置文件 6.使用依赖关系注入容器注册数据库上下文 7.添加基架工具并执行初始迁移 1.引言 NetCore出来有一 ...

  4. Bitnami WordPress如何让默认URL指向WordPress目录?

    Bitnami WordPress下载地址:https://bitnami.com/stack/wordpress/installer ,根据自己操作系统选择对应版本,我是windows server ...

  5. Java之static静态代码块

    Java之static静态代码块 构造代码块 使用{}包裹的代码区域,这里的代码区域特指位于class{}下面的而不是存在于其他type method(){}这类函数下面的代码区域 public cl ...

  6. 最后一个 last-of-type

    last-of-type这个比较好点,有时候:last-child 不起作用

  7. “全栈2019”Java第四十四章:继承

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  8. [Maven实战-许晓斌]-[第二章]-2.2基于UNIX系统安装maven

    >> >> >>3  

  9. memcached服务

    介绍 它是一套数据缓存系统或软件 用于动态应用系统中缓存数据库的数据,减少数据库的访问压力,达到提升性能的效果,实际应用环境中多用于数据库的cache的应用.它是通过预分配指定的内存空间来存储数据 定 ...

  10. mysql主从同步错误,提示The server quit without updating PID file

    在安装完lnmp后,启动mysqld失败,提示 [root@centos-6 ~]# service mysqld start Starting MySQL [确定][root@centos-6 ~] ...