树上背包?

问最少断掉多少条边可以形成节点数为k的块

设f[i,j]表示以节点i为根,形成一个节点数为k的块要断多少条边

则有:f[x,j]:=min(f[x,j],f[x,j-k]+f[y,k]-2) y是x的孩子

为什么要减2,现在装入以y为节点的子树,x和y之间的边,这条边自然不用断了,但在计算f[y,k]和f[x,1]的时候,这条边被断了两次

 const max=;
var f,son:array[..,..] of longint;
    fa,s,t:array[..] of longint;
    j,x,y,i,n,m,root,ans:longint; procedure treedp(x:longint);
  var i,y,j,k:longint;
  begin
    t[x]:=;
    for i:= to s[x] do
    begin
      treedp(son[x,i]);
      t[x]:=t[x]+t[son[x,i]];   //先统计子树规模
    end;
    f[x,]:=s[x];
    if x<>root then inc(f[x,]);   //细节 注意要断他父亲和它之间的边
    for i:= to s[x] do
    begin
      y:=son[x,i];
      for j:=t[x] downto do   //注意背包的倒推,每个子树显然只能用一次,相当于01背包
        for k:= to t[y] do
          if j-k>= then f[x,j]:=min(f[x,j],f[x,j-k]+f[y,k]-)
          else break;
    end;   end; begin
  readln(n,m);
  for i:= to n- do
  begin
    readln(x,y);
    s[x]:=s[x]+;   //题目中给定了父子关系
    son[x,s[x]]:=y;
    fa[y]:=x;
  end;
  for i:= to n do
    for j:= to n do
      f[i,j]:=max;
  root:=;
  while fa[root]<> do inc(root);
  treedp(root);
  ans:=max;
  for i:= to n do           
    ans:=min(ans,f[i,m]);
  writeln(ans);
end.

很好的treedp,一般来说,treedp都是先dfs再回来做dp……

总的复杂度O(n^3);题目其实不难,多想想就好

poj1947的更多相关文章

  1. poj1947(树上分组背包)

    题目链接:https://vjudge.net/problem/POJ-1947 题意:给定一棵树,求得到一个结点数为p最少删多少条边. 思路: 明显的树形dp,分组背包.用dp[u][j]表示在结点 ...

  2. POJ1947 Rebuilding Roads[树形背包]

    Rebuilding Roads Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 11495   Accepted: 5276 ...

  3. [USACO2002][poj1947]Rebuilding Roads(树形dp)

    Rebuilding RoadsTime Limit: 1000MS Memory Limit: 30000KTotal Submissions: 8589 Accepted: 3854Descrip ...

  4. POJ1947 Rebuilding Roads

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

  5. POJ1947 Rebuilding Roads(树形DP)

    题目大概是给一棵树,问最少删几条边可以出现一个包含点数为p的连通块. 任何一个连通块都是某棵根属于连通块的子树的上面一部分,所以容易想到用树形DP解决: dp[u][k]表示以u为根的子树中,包含根的 ...

  6. 树形DP(Rebuilding Roads poj1947)

    题意:给出一颗树,求要形成一颗元素个数是p的子树,最少要去掉多少边 #include"stdio.h" #include"string.h" #include& ...

  7. POJ-1947 Rebuilding Roads (树形DP+分组背包)

    题目大意:将一棵n个节点的有根树,删掉一些边变成恰有m个节点的新树.求最少需要去掉几条边. 题目分析:定义状态dp(root,k)表示在以root为根节点的子树中,删掉一些边变成恰有k个节点的新树需要 ...

  8. POJ1947 - Rebuilding Roads(树形DP)

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

  9. poj1947(树形dp)

    题目链接:http://poj.org/problem?id=1947 题意:给n(n<=150)个点的一棵树,求删掉最少边数k使得最后该树只剩下p(1<=p<=n)个节点.(求最小 ...

随机推荐

  1. Spark Streaming揭秘 Day30 集群模式下SparkStreaming日志分析

    Spark Streaming揭秘 Day30 集群模式下SparkStreaming日志分析 今天通过集群运行模式观察.研究和透彻的刨析SparkStreaming的日志和web监控台. Day28 ...

  2. psp系统需求分析

    软件开发方向“PSP系统”软件需求规约 目录 1 引言... 4 1.1 目的... 4 1.2 文档格式... 4 1.3 预期的读者和阅读建议... 4 1.4 范围... 5 1.5 术语... ...

  3. Oracle SQL的硬解析、软解析、软软解析

    Oracle中每条sql在执行前都要解析,解析分为硬解析.软解析.软软解析. Oracle会缓存DML语句,相同的DML语句会进行软解析.但不会缓存DDL语句,所以DDL每次都做硬解析.硬解析是一个很 ...

  4. Linux安装oracle 10g常见问题之——ORA-01078,LRM-00109,ORA-01102

    [oracle@toughhou database]$ sqlplus /nolog SQL> conn / as sysdba SQL> startup ORA-01078: failu ...

  5. NSFileManager 沙盒文件管理

    文件夹创建,复制,移动,删除,检查是否存在,代码如下: 1.获取沙盒 document 路径,作为文件夹路径的基路径. NSString *document = NSSearchPathForDire ...

  6. [转载]面向对象设计(OOD)思想(C#)

    有了思想才能飞翔,缺乏灵活就象少了轮子的汽车,难以飞奔.为了更好的理解设计思想,结合一个尽可能简洁的实例来说明OOD.设计模式及重构.通过下面的代码,详细地阐述面向对象设计思想. 一.传统过程化设计思 ...

  7. KafkaSpout分析:配置

    public KafkaSpout(SpoutConfig spoutConf) { _spoutConfig = spoutConf;} 基于0.93版本的Storm SpoutConfig继承自K ...

  8. linux telnet命令参数及用法详解--telnet连接远程终端命令

    功能说明:远端登入. 语 法:telnet [-8acdEfFKLrx][-b<主机alias.html' target='_blank'>别名>][-e<脱离字符>][ ...

  9. SSH架构简单总结

    Struts.spring.Hibernate在各层的作用 1)struts 负责 web层.    ActionFormBean 接收网页中表单提交的数据,然后通过Action 进行处理,再Forw ...

  10. 一分钟明白 VS manifest 原理

    什么是vs 程序的manifest文件 manifest 是VS程序用来标明所依赖的side-by-side组建,如ATL, CRT等的清单. 为什么要有manifest文件 一台pc上,用一组建往往 ...