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的边,求有多少边满足条件? 思路: 首先,这道题也可 ...
随机推荐
- Guitar
nuomi N3380614240045529680 N3380614240167717364 1404679948665073 装修风格: http://www.douban.com/group/t ...
- 【JZOJ4887】【NOIP2016提高A组集训第13场11.11】最大匹配
题目描述 mhy12345学习了二分图匹配,二分图是一种特殊的图,其中的点可以分到两个集合中,使得相同的集合中的点两两没有连边. 图的"匹配"是指这个图的一个边集,里面的边两两不存 ...
- linux驱动开发满三年,回首一下基本看不到其它选择
刚刚搞完一个处理器BSP项目,准备搞下一个自研处理器.说不上来什么喜悦,仅仅有些许茫然.没有刚毕业时对这个行业的痴迷,慢慢认同这仅仅是个谋生工具的想法. 回忆当初编写第一个驱动,就像上了战场.被长官踢 ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第六章:在Direct3D中绘制
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第六章:在Direct3D中绘制 代码工程地址: https://gi ...
- python 函数定义与调用时,不定长参数的传入
- docker的ubuntu镜像无ifconfig和ping命令
docker的ubuntu镜像无ifconfig和ping命令 或者 ubuntu系统中无ifconfig 和 ping 解决方案: 执行以下鸣冷: apt-get update apt-get in ...
- margin负边距的使用(超简单)
写在开头: 在css的世界中,一切都是框,所有的框都处于流动的状态 margin负边距可以使文档流发生偏移 在没有设置margin-bottom的时候,parent的高度会跟随child的内部元素 ...
- 【NS2】学习点滴
1 $ns duplex-link-op $n2 $n3 queuePos 0.5#此命令用于设置在NAM中显示的队列方向#经测试,发现: # queuePos 0.5表示包从上到下进入队列# que ...
- ssh 出错 Permission denied (publickey,password).
将客户端的~/.ssh/know_hosts 文件删掉试试 ssh debug信息 ssh -vvv xxx@192.168.1.111
- oracle函数 UPPER(c1)
[功能]将字符串全部转为大写 [参数]c1,字符表达式 [返回]字符型 [示例] SQL> select upper('AaBbCcDd') upper from dual; UPPER --- ...