因为上次比赛sb地把一道树形dp当费用流做了,受了点刺激,用一天时间稍微搞一下树形DP,今后再好好搞一下)

基于背包原理的树形DP

poj 1947 Rebuilding Roads

题意:给你一棵树,让你求最少剪掉多少条边可以剪出一棵点数为m的子树.

解法:dp[i][j]表示i节点得到j个节点的子树至少要剪多少边,对于每个节点a和它的孩子b,如果剪掉b,则dp(s)[a][j]=dp(s-1)[a][j], 如果保留<a,b>dp(s)[a][j]=min{dp(s-1)[a][j - k] + dp[b][k]}.初始条件为dp[a][1] = 0;

为了不产生后效性,需要由大到小枚举j的值。ans=min{dp[i][m] + 1,dp[root][m]}

  1. void dfs(int a) {
  2. dp[a][1] = 0;
  3. for (int i = E[a]; i != -1; i = buf[i].ne) {
  4. int b = buf[i].be;
  5. dfs(b);
  6. num[a]+=num[b];
  7. for (int j =Math.min(m,num[a]); j > 0; j--) {
  8. dp[a][j]++;
  9. for (int k = 1; k <= j&&k<=num[b]; k++)
  10. dp[a][j] = Math.min(dp[a][j], dp[a][j - k] + dp[b][k]);
  11. }
  12. }
  13. }
void dfs(int a) {
dp[a][1] = 0;
for (int i = E[a]; i != -1; i = buf[i].ne) {
int b = buf[i].be;
dfs(b);
num[a]+=num[b];
for (int j =Math.min(m,num[a]); j > 0; j--) {
dp[a][j]++;
for (int k = 1; k <= j&&k<=num[b]; k++)
dp[a][j] = Math.min(dp[a][j], dp[a][j - k] + dp[b][k]);
}
}
}

poj 1155 TELE 

题意:其余点为转发站。客户端i愿支付的钱为pay[i],每条边需要的花费固定,问电台在保证不亏损的情况下,解法:dp[a][j] = Math.max(dp[a][j], dp[a][j - k] + dp[b][k]- buf[i].v);节点a给j个节点输送信号能赚多少钱 j k num有N座城堡,每座城堡都有一定的宝物,允许攻克M个城堡并获得里面的宝物。但有些城堡必须先攻克其他某一个特定的城堡才能攻克,问攻克M个城堡所获得的最多宝物的数量。

dp[a][j] = Math.max(dp[a][j], dp[a][k] + dp[b][j - k]);dp[a][j]代表从i开始攻克j的城堡的最大获利,初始化时dp[i][1]=i城堡内的宝贝数,dp[0][1]=0;dp[i][0]=0;ans=Max{dp[i][m],dp[0][m+1]};

------------------------------------------------------------------------------------------------------

Poj 2486 Apple Tree

题意:苹果树上有n个节点,每个节点数上有若干个苹果,问最多走m步后至多能吃多少个苹果。

解法:每个在路径上的节点有两种形态:一是以此节点为起点到达某点后不再返回,而是从此节点出发后返回再从其它孩子继续走。因此定义dp[a][j][0]为a节点第一种情况下走j步的最大获利dp[a][j][1]为a节点在第二种情况下走j步的最大获利。转移方程为:

dp[a][j][0]=Math.max(dp[a][j][0],dp[a][k][1]+dp[b][j-k-1][0]);
dp[a][j][0]=Math.max(dp[a][j][0],dp[a][k][0]+dp[b][j-k-2][1]);
dp[a][j][1]=Math.max(dp[a][j][1],dp[a][k][1]+dp[b][j-k-2][1])

初始化dp[i][0][1]=dp[i][0][0]=i节点的苹果数。ans=Max{0,dp[1][i][0]};

Poj 1655 balancing Act/poj 3107 Godfather

题意:一个节点的平衡因子定义为:删到此节点后形成的节点数最多的子树。求一棵树中平衡因子最大的节点。

解法,定义num[i]为i节点为根的子树的节点数max[i]为i节点孩子节点数的最大值,一个节点的平衡因子=ans= Math.max(ans, first + second);

Sgu149&&HDU2196 Computer

解法:一个点的最远路径或者是向下一直走或者是先走到父节点然后再从父节点开始走一条较长的路径。
     对于第一种情况由底向上更新求出每点的最长路径和次长路径即可;对于第二种情况,如果当前节点是父节点最长路径上的点,那么向上的最长路径=边权+父节点的次长路径,否则最长路径=边权+父节点的最长路径。得到向上的最长路径后更新最长路径和次长路径(如果更新了最长路径,需要更新一下原来向下最大孩子的状态,使它不是父节点最长路径上的点),从上向下dfs更新一下即可。

  1. int dfs(int a) {
  2. int temp, f = 0;
  3. for (int i = E[a]; i != -1; i = buf[i].ne) {
  4. int b = buf[i].be;
  5. temp = dfs(b) + buf[i].v;
  6. if (temp > first[a]) {
  7. second[a] = first[a];
  8. first[a] = temp;
  9. f = b;
  10. }
  11. else if(temp>second[a])
  12. second[a]=temp;
  13. }
  14. fid[a] = f;
  15. isf[f] = true;
  16. return first[a];
  17. }
  18. void work(int p, int a, int v) {
  19. int temp = -1;
  20. if (isf[a])
  21. temp = second[p] + v;
  22. else
  23. temp = first[p] + v;
  24. if (temp > first[a]) {
  25. second[a] = first[a];
  26. first[a] = temp;
  27. isf[fid[a]] = false;
  28. } else if (temp > second[a])
  29. second[a] = temp;
  30. for (int i = E[a]; i != -1; i = buf[i].ne) {
  31. int b = buf[i].be;
  32. work(a, b, buf[i].v);
  33. }
  34. }
int dfs(int a) {
int temp, f = 0;
for (int i = E[a]; i != -1; i = buf[i].ne) {
int b = buf[i].be;
temp = dfs(b) + buf[i].v;
if (temp > first[a]) {
second[a] = first[a];
first[a] = temp;
f = b;
}
else if(temp>second[a])
second[a]=temp;
}
fid[a] = f;
isf[f] = true;
return first[a];
} void work(int p, int a, int v) {
int temp = -1;
if (isf[a])
temp = second[p] + v;
else
temp = first[p] + v;
if (temp > first[a]) {
second[a] = first[a];
first[a] = temp;
isf[fid[a]] = false;
} else if (temp > second[a])
second[a] = temp; for (int i = E[a]; i != -1; i = buf[i].ne) {
int b = buf[i].be;
work(a, b, buf[i].v);
}
}

DP Intro - Tree DP Examples的更多相关文章

  1. DP Intro - Tree DP

    二叉苹果树 题目 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点 ...

  2. DP Intro - Tree POJ2342 Anniversary party

    POJ 2342 Anniversary party (树形dp 入门题) Anniversary party Time Limit: 1000MS   Memory Limit: 65536K To ...

  3. HDU5293(SummerTrainingDay13-B Tree DP + 树状数组 + dfs序)

    Tree chain problem Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Other ...

  4. HDU3534(SummerTrainingDay13-C tree dp)

    Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  5. Partial Tree(DP)

    Partial Tree http://acm.hdu.edu.cn/showproblem.php?pid=5534 Time Limit: / MS (Java/Others) Memory Li ...

  6. 96. Unique Binary Search Trees (Tree; DP)

    Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For examp ...

  7. DP Intro - poj 1947 Rebuilding Roads(树形DP)

    版权声明:本文为博主原创文章,未经博主允许不得转载. Rebuilding Roads Time Limit: 1000MS   Memory Limit: 30000K Total Submissi ...

  8. HDU 4359——Easy Tree DP?——————【dp+组合计数】

    Easy Tree DP? Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  9. TYOI Day1 travel:Tree dp【处理重复走边】

    题意: 给你一棵树,n个节点,每条边有长度. 然后有q组询问(u,k),每次问你:从节点u出发,走到某个节点的距离mod k的最大值. 题解: 对于无根树上的dp,一般都是先转成以1为根的有根树,然后 ...

随机推荐

  1. 编写高质量代码改善C#程序的157个建议——建议24:迭代器应该是只读的

    建议24:迭代器应该是只读的 如果注意观察会发现,FCL中的迭代器只有GetEnumerator方法,没有SetEnumerator方法,所有的集合类也没有一个可以写的迭代器属性.原因有二: 一:这违 ...

  2. 国外物联网平台(5):Exosite Murano

    国外物联网平台(5)——Exosite Murano 马智 定位 Murano是一个基于云的IoT软件平台,提供安全.可扩展的基础设施,支持端到端的生态系统,帮助客户安全.可扩展地开发.部署和管理应用 ...

  3. HTML <area> 标签区域map标签

    1.距形:(左上角顶点坐标为(x1,y1),右下角顶点坐标为(x2,y2)) <area shape="rect" coords="x1,y1,x2,y2" ...

  4. lda:变分的推导

    lda,latent diriclet allocation,是一个最基本的bayesian模型.本文要研究lda基于变分的推导方法.意义是重大的. 一.符号的定义 : the number of t ...

  5. NET上传大文件出现网页无法显示的问题 默认的上传文件大小是4M

    需要在配置文件处进行修改 web.config中的<system.web></system.web>内加入如下代码: <httpRuntime executionTime ...

  6. Day 3 Python 基础数据类型二

    1. INT 型 #1. 数字int #bit_length() 当十进制用二进制表示时,最少使用的位数. v =11 data = v.bit_length() print(data) 2. 布尔值 ...

  7. 动态内存分配存在的问题(内存空洞)------c++程序设计原理与实践(进阶篇)

    new的问题究竟在哪里呢?实际上问题出在new和delete的结合使用上.考察下面程序中内存分配和释放过程: while(1){ Big* p=new big; //...... Small* n1= ...

  8. NFS4 挂载同主机多个目录

    写在前面的话 事情是酱婶儿的,前两天实在是帮他们查日志查的心里交瘁了,而且有些时候下班了,也就不想再接到这样的需求,于是想基于 Nginx 做一个文件下载中心,在这个文件下载中心里面存有各个服务的日志 ...

  9. C# LINQ(5)

    目前都是说的单数据差距,如果多数据进行查询LINQ该如何呢? 那么LINQ就应该使用关键字 join on equals 现有代码: static void Main(string[] args) { ...

  10. MVC进阶篇(三)——model层数据验证

    前言 常常在想,姓名性别那些个验证,真的有必要每次遇到,每次写验证吗?好麻烦,于是学到MVC这里,发现MVC自带数据验证,这个东西着实是个好东西.我写了一个小demo,分享给大家. 内容 一个表单的提 ...