HDU 6662 Acesrc and Travel (换根dp)
However, Zhang and Liu have different preferences for these spots. They respectively set a satisfactory value for each spot. If they visit the ith spot, Zhang will obtain satisfactory value ai, and Liu will obtain bi. Starting with Zhang, they alternately decide the next spot to visit for the sake of fairness. There must be a bus route between the current spot and the next spot to visit. Moreover, they would never like to visit a spot twice. If anyone can't find such a next spot to visit, they have no choice but to end this travel.
Zhang and Liu are both super smart competitive programmers. Either want to maximize the difference between his total satisfactory value and the other's. Now Acesrc wonders, if they both choose optimally, what is the difference between total satisfactory values of Zhang and Liu?
For each test case, the first line contains a single integer n (1≤n≤105), denoting the number of spots. Each of the next two lines contains n integers, a1,a2,⋯,anand b1,b2,⋯,bn (0≤ai,bi≤109), denoting the
satisfactory value of Zhang and Liu for every spot, respectively. Each of the last n−1 lines contains two integers x,y (1≤x,y≤n,x≠y), denoting a bus route between the xth spot and the yth spot. It is reachable from any spot to any other spot through these bus routes.
It is guaranteed that the sum of n does not exceed 5.01×105.
3
1 1 1
0 2 3
1 2
1 3
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime> #define fuck(x) cerr<<#x<<" = "<<x<<endl;
#define debug(a, x) cerr<<#a<<"["<<x<<"] = "<<a[x]<<endl;
#define lson l,mid,ls
#define rson mid+1,r,rs
#define ls (rt<<1)
#define rs ((rt<<1)|1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int loveisblue = ;
const int maxn = ;
const int maxm = ;
const ll Inf = 0x3f3f3f3f3f3f3f3f;
const int mod = ;
const double eps = 1e-;
const double pi = acos(-); int Head[maxn], cnt;
struct edge {
int Next, v;
} e[maxm]; void add_edge(int u, int v) {
e[cnt].Next = Head[u];
e[cnt].v = v;
Head[u] = cnt++;
} ll a[maxn]; ll dp1[][maxn];//0由第一个人选择而来,1第二个选择而来
ll dp2[][maxn];//次
bool vis[maxn]; void dfs(int u, int fa) {
bool flag = true;
for (int k = Head[u]; k != -; k = e[k].Next) {
if (e[k].v == fa) {
continue;
}
dfs(e[k].v, u);
flag = false; ll tmp1 = dp1[][e[k].v];
ll tmp0 = dp1[][e[k].v]; //当前由第一个人选择而来的,那下一个一定由第二个人选择而来
if (tmp1 < dp2[][u]) { swap(tmp1, dp2[][u]); }
if (dp2[][u] < dp1[][u]) { swap(dp2[][u], dp1[][u]); } if (tmp0 > dp2[][u]) { swap(tmp0, dp2[][u]); }
if (dp2[][u] > dp1[][u]) { swap(dp2[][u], dp1[][u]); }
} vis[u] = flag;
//叶子节点的特殊处理
if (flag) {
dp1[][u] = ;
dp1[][u] = ;
}
if (dp1[][u] != Inf) dp1[][u] += a[u];
if (dp1[][u] != -Inf) dp1[][u] += a[u];
if (dp2[][u] != Inf) dp2[][u] += a[u];
if (dp2[][u] != -Inf) dp2[][u] += a[u];
} ll ans = -Inf; void dfs1(int u, int fa) { ll tmp0 = dp1[][fa];
ll tmp1 = dp1[][fa]; //如果父亲节点的最值是由u转移来的,那么就要利用次值换根
if (tmp0 == dp1[][u] + a[fa]) {
tmp0 = dp2[][fa];
}
if (tmp1 == dp1[][u] + a[fa]) {
tmp1 = dp2[][fa];
} //如果fa是只有u这一个儿子,并且fa==1时,才会出现这种情况
if (tmp1 == -Inf) {
tmp1 = a[fa];
}
if (tmp0 == Inf) {
tmp0 = a[fa];
}
tmp0 += a[u];
tmp1 += a[u]; //u是叶子节点,直接特判
if (vis[u]) {
ans = max(ans, tmp1);
}
//此段代码和dfs中的完全相同
if (tmp1 < dp2[][u]) { swap(tmp1, dp2[][u]); }
if (dp2[][u] < dp1[][u]) { swap(dp2[][u], dp1[][u]); } if (tmp0 > dp2[][u]) { swap(tmp0, dp2[][u]); }
if (dp2[][u] > dp1[][u]) { swap(dp2[][u], dp1[][u]); } ans = max(ans, dp1[][u]); for (int k = Head[u]; k != -; k = e[k].Next) {
if (e[k].v != fa)dfs1(e[k].v, u);
}
} int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
int T;
scanf("%d", &T);
while (T--) {
int n;
ans = -Inf;
cnt = ;
scanf("%d", &n);
for (int i = ; i <= n; i++) {
Head[i] = -;
scanf("%lld", &a[i]);
dp1[][i] = dp2[][i] = Inf;
dp1[][i] = dp2[][i] = -Inf; }
for (int i = ; i <= n; i++) {
ll x;
scanf("%lld", &x);
a[i] -= x;
}
for (int i = ; i < n; i++) {
int x, y;
scanf("%d%d", &x, &y);
add_edge(x, y);
add_edge(y, x);
}
dfs(, );
ans = dp1[][];
for (int k = Head[]; k != -; k = e[k].Next) {
dfs1(e[k].v, );
}
printf("%lld\n", ans);
}
return ;
}
对代码有问题可以留言
HDU 6662 Acesrc and Travel (换根dp)的更多相关文章
- HDU 6662 Acesrc and Travel 换根DP,宇宙最傻记录
#include<bits/stdc++.h> typedef long long ll; using namespace std; const int maxn=1e6+50; cons ...
- Acesrc and Travel(2019年杭电多校第八场06+HDU6662+换根dp)
题目链接 传送门 题意 两个绝顶聪明的人在树上玩博弈,规则是轮流选择下一个要到达的点,每达到一个点时,先手和后手分别获得\(a_i,b_i\)(到达这个点时两个人都会获得)的权值,已经经过的点无法再次 ...
- [BZOJ4379][POI2015]Modernizacja autostrady[树的直径+换根dp]
题意 给定一棵 \(n\) 个节点的树,可以断掉一条边再连接任意两个点,询问新构成的树的直径的最小和最大值. \(n\leq 5\times 10^5\) . 分析 记断掉一条边之后两棵树的直径为 \ ...
- 2018.10.15 NOIP训练 水流成河(换根dp)
传送门 换根dp入门题. 貌似李煜东的书上讲过? 不记得了. 先推出以1为根时的答案. 然后考虑向儿子转移. 我们记f[p]f[p]f[p]表示原树中以ppp为根的子树的答案. g[p]g[p]g[p ...
- 换根DP+树的直径【洛谷P3761】 [TJOI2017]城市
P3761 [TJOI2017]城市 题目描述 从加里敦大学城市规划专业毕业的小明来到了一个地区城市规划局工作.这个地区一共有ri座城市,<-1条高速公路,保证了任意两运城市之间都可以通过高速公 ...
- 小奇的仓库:换根dp
一道很好的换根dp题.考场上现场yy十分愉快 给定树,求每个点的到其它所有点的距离异或上m之后的值,n=100000,m<=16 只能线性复杂度求解,m又小得奇怪.或者带一个log像kx一样打一 ...
- 国家集训队 Crash 的文明世界(第二类斯特林数+换根dp)
题意 题目链接:https://www.luogu.org/problem/P4827 给定一棵 \(n\) 个节点的树和一个常数 \(k\) ,对于树上的每一个节点 \(i\) ,求出 \( ...
- bzoj 3566: [SHOI2014]概率充电器 数学期望+换根dp
题意:给定一颗树,树上每个点通电概率为 $q[i]$%,每条边通电的概率为 $p[i]$%,求期望充入电的点的个数. 期望在任何时候都具有线性性,所以可以分别求每个点通电的概率(这种情况下期望=概率 ...
- codeforces1156D 0-1-Tree 换根dp
题目传送门 题意: 给定一棵n个点的边权为0或1的树,一条合法的路径(x,y)(x≠y)满足,从x走到y,一旦经过边权为1的边,就不能再经过边权为0的边,求有多少边满足条件? 思路: 首先,这道题也可 ...
随机推荐
- LeetCode153 Find Minimum in Rotated Sorted Array. LeetCode162 Find Peak Element
二分法相关 153. Find Minimum in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unkn ...
- JAVA高级特性--String/StringBuffer/Builder
String String对象一旦创建就不能改变 是常量 需要进行大量字符串操作应采用StringBuffer/StringBuilder 最终结果转换成String对象 StringBuffer ...
- SDUT_2502:火星计数法
火星人的计数规则里只有a,b,c,d四个字母,计数规则从小到大是 a,b,c,d,aa,ab,ac,ad,ba,……. 给出来由a,b,c,d四种字母组成的火星数字,算出该数字是第几个(从1开始). ...
- Android 高仿微信支付键盘
现在很多app的支付.输入密码功能,都已经开始使用自定义数字键盘,不仅更加方便.其效果着实精致. 下面带着大家学习下,如何高仿微信的数字键盘,可以拿来直接用在自身的项目中. 先看下效果图: 1. 自定 ...
- poj 2342 hdu 1520【树形dp】
poj 2342 给出每个顶点的happy值,还有若干组两个顶点L,K关系,表示K是L的上司.求当K.L不同时出现时获得的happy值的最大和. 设dp[u][0]表示不选u结点时获得的最大值,dp[ ...
- 二 virtualenv与virtualenvwrapper
https://www.cnblogs.com/pyyu/p/9015317.html 一 virtualenv 1.下载virtualenvpip3 install -i https://pypi ...
- C++与JAVA代码实现CRC-16/MODBUS算法,且与 http://www.ip33.com/crc.html 进行结果验证
CRC-16/MODBUS的多项式为:x16+x15+x2+1(8005),宽度为16.运算时,首先将一个16位的寄存器预置为11111111 11111111,然后连续把数据帧中的每个字节中的8位与 ...
- @codeforces - 702F@ T-Shirts
目录 @description@ @solution@ @accepted code@ @details@ @description@ 有 n 件 T-shirt,第 i 件 T-shirt 有一个 ...
- js+canvas黑白棋
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- SDUT-3332&3333_数据结构实验之栈与队列五:下一较大值
数据结构实验之栈与队列六:下一较大值 Time Limit: 150 ms Memory Limit: 8000 KiB Problem Description 对于包含n(1<=n<=1 ...