HDU 6201 2017沈阳网络赛 树形DP或者SPFA最长路
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6201
题意:给出一棵树,每个点有一个权值,代表商品的售价,树上每一条边上也有一个权值,代表从这条边经过所需要的花费。现在需要你在树上选择两个点,一个作为买入商品的点,一个作为卖出商品的点,当然需要考虑从买入点到卖出点经过边的花费。使得收益最大。允许买入点和卖出点重合,即收益最小值为0。
解法:我们设1为根节点,假设一开始一个人身上的钱为0。我们设dp[i][0]表示从根节点走到i及其子树并中任一点买入一本书后这个人身上钱的最大值(显然是负的)。dp[i][1]表示从根节点走到i及其子树并中任一点卖出一本书后这个人身上钱的最大值(可正可负)。那么我们对这棵树进行一次树形DP即可,dfs后对每个节点更新收益最大值,单点的计算方法为dp[i][0]+dp[i][1],树形DP的过程中即可维护这个最大值。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 100010;
struct node{
int v,w;
};
vector <node> G[maxn];
int val[maxn];
int dp[maxn][2];
int n, ans;
void dfs(int x, int pre){
dp[x][0] = -val[x];
dp[x][1] = val[x];
for(int i=0; i<G[x].size(); i++){
int v = G[x][i].v;
int w = G[x][i].w;
if(v == pre) continue;
dfs(v, x);
dp[x][0] = max(dp[x][0], dp[v][0]-w);
dp[x][1] = max(dp[x][1], dp[v][1]-w);
}
ans = max(ans, dp[x][0]+dp[x][1]);
}
int main()
{
int T;
scanf("%d", &T);
while(T--){
scanf("%d", &n);
for(int i=0; i<=n; i++) G[i].clear();
for(int i=1; i<=n; i++) scanf("%d", &val[i]);
for(int i=1; i<n; i++){
int u, v, w;
scanf("%d %d %d", &u,&v,&w);
G[u].push_back(node{v,w});
G[v].push_back(node{u,w});
}
ans = 0;
dfs(1,-1);
printf("%d\n", ans);
}
return 0;
}
除了DP,还看到一个方法,就是建立源点和汇点。源点连所有的树上点, 边权为 a[i], 所有树上点在连接 汇点, 边权为-a[i]. 然后在根据树建图。 spfa跑个最长路即可。这个也可以用费用流,不过要注意是可行流。
HDU 6201 2017沈阳网络赛 树形DP或者SPFA最长路的更多相关文章
- HDU 6199 2017沈阳网络赛 DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6199 题意:n堆石子,Alice和Bob来做游戏,一个人选择取K堆那么另外一个人就必须取k堆或者k+1 ...
- HDU 6198 2017沈阳网络赛 线形递推
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6198 题意:给出一个数k,问用k个斐波那契数相加,得不到的数最小是几. 解法:先暴力打表看看有没有规律 ...
- HDU 6200 2017沈阳网络赛 树上区间更新,求和
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6200 题意:给个图,有2种操作,一种是加一条无向边,二是查询u,v之间必须有的边的条数,所谓必须有的边 ...
- HDU 6203 2017沈阳网络赛 LCA,DFS+树状数组
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6203 题意:n+1 个点 n 条边的树(点标号 0 ~ n),有若干个点无法通行,导致 p 组 U V ...
- HDU 6205 2017沈阳网络赛 思维题
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6205 题意:给你n堆牌,原本每一堆的所有牌(a[i]张)默认向下,每次从第一堆开始,将固定个数的牌(b ...
- HDU 6195 2017沈阳网络赛 公式
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6195 题意:有M个格子,有K个物品.我们希望在格子与物品之间连数量尽可能少的边,使得——不论是选出M个 ...
- 2019沈阳网赛树形dp
https://nanti.jisuanke.com/t/41403 2019沈阳网络赛D题 树形dp.一棵树,求任意两个点的距离之和.u-v和v-u算两次.两点之间的距离分为三类,模3等于0,1,2 ...
- HDU 6201 transaction transaction transaction(树形DP)
transaction transaction transaction Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 132768/1 ...
- HDU 6212 Zuma 2017青岛网络赛 区间DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6212 解法:看了眼题就发现这个BZOJ 1032不是一毛一样?但是BZOJ上那是个巨坑,数据有错,原来 ...
随机推荐
- [AT2172] [agc007_e] Shik and Travel
题目链接 AtCoder:https://agc007.contest.atcoder.jp/tasks/agc007_e 洛谷:https://www.luogu.org/problemnew/sh ...
- 【51Nod1258】序列求和V4(FFT)
[51Nod1258]序列求和V4(FFT) 题面 51Nod 多组数据,求: \[Ans=\sum_{i=1}^ni^k,n\le 10^{18},k\le50000\] 题解 预处理伯努利数,时间 ...
- unity3d点击屏幕选中物体
原文 http://blog.csdn.net/mycwq/article/details/19906335 前些天接触unity3d,想实现点击屏幕选中物体的功能.后来研究了下,实现原理就是检测从 ...
- S-T平面图
给定一个平面图和一个源点S.汇点T都在图中无边界的区域上,这样的图叫S-T平面图 我们把图中每一个独立的面看做一个点,对于每条边e,将它两侧的面连一条边,其中靠近S的一段与S相连,与T相连的一段与T相 ...
- JS中如何使用EL表达式中的对象
JS中如何使用EL表达式中的对象 2017年09月25日 15:33:09 lhpnba 阅读数:4859 1.js中使用el表达式要加双引号或单引号:'${list}' 2.js变量获取el表达 ...
- angular 有关侦测组件变化的 ChangeDetectorRef 对象
我们知道,如果我们绑定了组件数据到视图,例如使用 <p>{{content}}</p>,如果我们在组件中改变了content的值,那么视图也会更新为对应的值. angular ...
- thinkphp常见问题
1.数据库查询中execute和query方法的区别 tp中execute()和query()方法都可以在参数里直接输入sql语句. 但是不同的是execute()通常用来执行insert或者upda ...
- C++并发编程 thread
std::thread C++11在标准库中为多线程提供组件, 使用线程需要包含头文件 thread, 其命名空间为 std. 启动新线程 每个进程至少有一个线程: 执行main()函数的线程, 其余 ...
- 我学习的第一个uiautomator从创建到运行结束
一.新建自动化脚本 1.新建java工程包 [file]----[new]----[Java Project] 新建工程 [右 ...
- 配置ntpd时钟同步服务
ntpd时钟同步服务 目录 参考: CentOS配置时间同步NTP: http://www.crsay.com/wiki/wiki.php/server/centos/ntp-set 解决ntp的错误 ...