题意:一棵树有点权和边权 从每个点出发 走过一条边要花费边权同时可以获得点权 边走几次就算几次花费 点权最多算一次

   问每个点能获得的最大价值

题解:好吧 这才叫树形DP入门题

   dp[i][0]表示从i节点的儿子中走又回到i的最大值 dp[i][1]表示不回到i的最大值 dp[i][2]表示不回到i的次大值

   同时需要记录不回到i最大值的方向id[x]

   很显然 第一遍dfs可以预处理每个节点往下的值 然后关键的就是每个节点从父亲这个方向的值怎么处理

   有个很显然的结论就是 不回来是肯定比回来更优的 所以重点就是在处理不回来的这个支路在哪

   如果对于x节点其父亲的id[fa] = x 那么显然x,fa不回来的最大值是同一个支路 这个时候就可以更新两种答案

   在x下面的儿子中不回来 dp[x][1] = dp[x][1] += max(0, dp[fa][0] - cost[x][fa] * 2)

   在fa中的其他儿子中不回来就用到了次大 dp[x][1] = dp[x][0] + dp[fa][2] - cost[x][fa]

   如果id[fa] != x  dp[x][1] = dp[x][0] + dp[fa][1] - cost[x][fa]

   最后再更新dp[x][0] = dp[x][0] + max(0, dp[fa][0] - cost[x][fa] * 2) 同时转移的时候次大 以及最大的方向都要更新

   不过这里的dp值显然都是要减去重复计算的部分 具体代码见

#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
using namespace std; int n, cnt;
int q[];
int dp[][];
int du[];
int head[];
int id[]; struct node
{
int no, to, nex, val;
}E[]; void dfs1(int x, int fa)
{
dp[x][] = q[x];
dp[x][] = q[x];
dp[x][] = q[x];
int c = head[x];
for(int i = c; i; i = E[i].nex)
{
int v = E[i].to;
if(v == fa) continue; dfs1(v, x);
if(E[i].val * < dp[v][]) dp[x][] += dp[v][] - E[i].val * ;
} for(int i = c; i; i = E[i].nex)
{
int v = E[i].to;
if(v == fa) continue; int tmp = dp[x][];
if(E[i].val * < dp[v][]) tmp += E[i].val * - dp[v][]; if(tmp + dp[v][] - E[i].val >= dp[x][])
{
dp[x][] = dp[x][];
dp[x][] = tmp + dp[v][] - E[i].val;
id[x] = v;
}
else if(tmp + dp[v][] - E[i].val > dp[x][]) dp[x][] = tmp + dp[v][] - E[i].val; dp[x][] = max(dp[x][], dp[x][]);
}
} void dfs2(int x, int fa)
{
int c = head[x];
for(int i = c; i; i = E[i].nex)
{
int v = E[i].to;
if(v != fa) continue; int tmp0 = dp[fa][];
int tmp1 = dp[fa][];
int tmp2 = dp[fa][];
if(E[i].val * < dp[x][])
{
tmp0 += E[i].val * - dp[x][];
if(id[fa] != x) tmp1 += E[i].val * - dp[x][];
else tmp2 += E[i].val * - dp[x][];
}
tmp0 = max(tmp0, ); tmp1 = max(tmp1, ); tmp2 = max(tmp2, ); //dp[x][0] = max(dp[x][0], dp[x][0] - E[i].val * 2 + tmp0); 因为下面的转移用到了dp[x][0] 写在这里就不对
if(tmp0 - E[i].val * > )
{
dp[x][] += tmp0 - E[i].val * ;
dp[x][] += tmp0 - E[i].val * ;
} if(id[fa] == x)
{
if(dp[x][] - E[i].val + tmp2 >= dp[x][])
{
dp[x][] = dp[x][];
dp[x][] = dp[x][] - E[i].val + tmp2;
id[x] = fa;
}
else if(dp[x][] - E[i].val + tmp2 > dp[x][]) dp[x][] = dp[x][] - E[i].val + tmp2;
}
else
{
if(dp[x][] - E[i].val + tmp1 >= dp[x][])
{
dp[x][] = dp[x][];
dp[x][] = dp[x][] - E[i].val + tmp1;
id[x] = fa;
}
else if(dp[x][] - E[i].val + tmp1 > dp[x][]) dp[x][] = dp[x][] - E[i].val + tmp1;
}
dp[x][] = max(dp[x][], dp[x][] - E[i].val * + tmp0);
} for(int i = c; i; i = E[i].nex)
{
int v = E[i].to;
if(v == fa) continue;
dfs2(v, x);
}
} int main()
{
int T;
scanf("%d", &T);
int t = ; while(T--)
{
t++;
cnt = ;
scanf("%d", &n);
memset(id, , sizeof(id));
memset(head, , sizeof(head));
memset(dp, , sizeof(dp));
memset(du, , sizeof(du));
for(int i = ; i <= n; i++) scanf("%d", &q[i]); for(int i = ; i < n; i++)
{
int u, v, w; scanf("%d%d%d", &u, &v, &w); du[u]++; du[v]++;
E[++cnt].no = u, E[cnt].to = v, E[cnt].nex = head[u], head[u] = cnt, E[cnt].val = w;
E[++cnt].no = v, E[cnt].to = u, E[cnt].nex = head[v], head[v] = cnt, E[cnt].val = w;
} int rt;
for(int i = ; i <= n; i++)
if(du[i] == )
{
rt = i;
break;
} dfs1(rt, -);
dfs2(rt, -);
printf("Case #%d:\n", t);
for(int i = ; i <= n; i++) printf("%d\n", max(dp[i][], dp[i][]));
}
return ;
}

  

HDU5834 Magic boy Bi Luo with his excited tree (树形DP)的更多相关文章

  1. hdu-5834 Magic boy Bi Luo with his excited tree(树形dp)

    题目链接: Magic boy Bi Luo with his excited tree Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: ...

  2. hdu 5834 Magic boy Bi Luo with his excited tree 树形dp+转移

    Magic boy Bi Luo with his excited tree Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 13107 ...

  3. 树形DP CCPC网络赛 HDU5834 Magic boy Bi Luo with his excited tree

    // 树形DP CCPC网络赛 HDU5834 Magic boy Bi Luo with his excited tree // 题意:n个点的树,每个节点有权值为正,只能用一次,每条边有负权,可以 ...

  4. HDU5834 Magic boy Bi Luo with his excited tree(树形DP)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5834 Description Bi Luo is a magic boy, he also ...

  5. hdu5834 Magic boy Bi Luo with his excited tree 【树形dp】

    题目链接 hdu5834 题解 思路很粗犷,实现很难受 设\(f[i][0|1]\)表示向子树走回来或不回来的最大收益 设\(g[i][0|1]\)表示向父亲走走回来或不回来的最大收益 再设\(h[i ...

  6. HDU5834Magic boy Bi Luo with his excited tree 树形dp

    分析:典型的两遍dfs树形dp,先统计到子树的,再统计从祖先来的,dp[i][0]代表从从子树回来的最大值,dp[i][1]代表不回来,id[i]记录从i开始到哪不回来 吐槽:赛场上想到了状态,但是不 ...

  7. 2016中国大学生程序设计竞赛 - 网络选拔赛 C. Magic boy Bi Luo with his excited tree

    Magic boy Bi Luo with his excited tree Problem Description Bi Luo is a magic boy, he also has a migi ...

  8. 动态规划(树形DP):HDU 5834 Magic boy Bi Luo with his excited tree

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAA8UAAAJbCAIAAABCS6G8AAAgAElEQVR4nOy9fXQcxZ0uXH/hc8i5N+

  9. 【树形动规】HDU 5834 Magic boy Bi Luo with his excited tree

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5834 题目大意: 一棵N个点的有根树,每个节点有价值ci,每条树边有费用di,节点的值只能取一次,边 ...

随机推荐

  1. UM九图

    UML有9种图: 用例图类图对象图状态图序列图协作图活动图组件图部署图 9,在中国是个阳数,通常代表很多的意思.比如说,九九艳阳天,九死而不悔,成吉思汗对功臣的九罪而不罚,天上九头鸟地上湖北佬,等等. ...

  2. libXdmcp.so.6

    Traceback (most recent call last): File "/data/xiaole_dl_img/product.v.one.banner.fixedperiod.g ...

  3. 20170626_oracle_数据库设计

    数据库设计的定义:规划数据库中数据对象以及之间关系的过程. 为什么进行数据库设计? 空间 完整性 程序开发 数据库设计前提知识: 范式: 1NF:第一范式 第一范式的目标是确保每列的原子性 如果每列都 ...

  4. bzoj4974: [Lydsy1708月赛]字符串大师

    脑洞题...玄学 假如是a[i]!=i,说明构成了循环节长为a[i]的循环,那就去%一下(别想多)看一下是循环节中的第几个咯. 否则新填的这个不能和前面构成任何循环,那就不停往前跳去把不能填的标记一下 ...

  5. 【Codevs1183】泥泞的道路

    Position: http://codevs.cn/problem/1183/ List Codevs1183 泥泞的道路 List Description Input Output Sample ...

  6. 【转】Material Design 折叠效果 Toolbar CollapsingToolbarLayout AppBarLayout

    我非常喜欢Material Design里折叠工具栏的效果,bilibili Android客户端视频详情页就是采用的这种设计.这篇文章的第二部分我们就通过简单的模仿bilibili视频详情页的实现来 ...

  7. 编程细节 —— 按值传递、按引用传递(final、const)

    System.out,out 是 System 类内定义的静态 final PrinterStream 变量: public final class System { ... public final ...

  8. luogu 1966 火柴排队

    题目大意: 两列数,可以交换每列中相邻的两个数,算作一次交换 求最小的交换次数使两列数相对应的数之差的平方之和最小 思路: 首先可以明确当两列数的排序位置相对应时,为最佳答案 然后我们按照一中排序后在 ...

  9. 编译Ruby2.0 问题解决

    compiling readline.creadline.c: In function ‘Init_readline’:readline.c:1886:26: error: ‘Function’ un ...

  10. SqlServer数据库性能优化详解

    数据库性能优化详解 性能调节的目的是通过将网络流通.磁盘 I/O 和 CPU 时间减到最小,使每个查询的响应时间最短并最大限度地提高整个数据库服务器的吞吐量.为达到此目的,需要了解应用程序的需求和数据 ...