Acesrc and Travel
Acesrc and Travel
时间限制: 1 Sec 内存限制: 128 MB
题目描述
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,⋯,an and 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.
输出
样例输入
1
3
1 1 1
0 2 3
1 2
1 3
样例输出
-1
题意:有两个人轮流在一棵树上选择点,每个点有一个权值,A想让权值和最大,B想让权值和最小,下一次选择的点必须和这次选择的点有直接边连接,且点不能重复选择,A可以选择任意一个点作为初始点,问最后权值和是多少。
思路:考虑DP,但这是一个无根树,于是首先要转化成有根树DP,即首先把1号点作为根节点,然后DP算出:A或者B选择了某一个点,且上一步是从改点的父亲走过来的最优权值和。然后再考虑父亲反向边的DP,即计算出:A或者B选择了某一个点,且下一步是到改点的父亲的最优权值和。则答案就是在所有B选择点时,维护最大值。
总结:无根树DP就是有根树DP加上父亲反向边的DP。
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
using namespace std; const int N = 6e5+;
struct ss
{
int u,v,next;
};
ss edg[N*];
int head[N],sum_edge=; void addedge(int u,int v)
{
edg[sum_edge]=(ss){u,v,head[u]};
head[u]=sum_edge++;
} long long value[N];
long long ans=;
long long dp[N][]; void init(int n)
{
for(int i=;i<=n;i++)
{
head[i]=-;
dp[i][]=dp[i][]=;
}
sum_edge=;
ans=LLONG_MIN;
} long long dfs1(int x,int fa,int type)
{
if(dp[x][type])return dp[x][type];
long long now= (type== ? LLONG_MIN : LLONG_MAX); for(int i=head[x];i!=-;i=edg[i].next)
{
int v=edg[i].v;
if(v==fa)continue; if(type==)now=max(now,dfs1(v,x,)+value[x]);
else
now=min(now,dfs1(v,x,)+value[x]);
}
return dp[x][type]=((now==LLONG_MAX||now==LLONG_MIN) ? value[x] : now);
} long long dfs(int x,int fa,int type,long long last_ans)
{
// printf("%d %d %d %lld\n",x,fa,type,last_ans);
//printf("x=%d,fa=%d : %lld %lld value[%d]=%lld\n",x,fa,dfs1(x,fa,0),dfs1(x,fa,1),x,value[x]);
priority_queue<pair<long long,int> >q;
for(int i=head[x];i!=-;i=edg[i].next)
{
int v=edg[i].v;
if(v==fa)continue; if(type==)q.push(make_pair(-dfs1(v,x,),v));
else
q.push(make_pair(dfs1(v,x,),v)); if(q.size()>)q.pop();
} pair<long long,int> first;
pair<long long,int> second; if(q.size())
{
first=q.top();
q.pop();
// printf("%lld\n",first.first); if(q.size())
{
second=q.top();
// printf("%lld\n",second.first);
q.pop();
}
else
{
second=first; if(x!=)first=make_pair(LLONG_MAX/,-);
else
first=make_pair(,-);
}
}
else
{
if(x!=)second=make_pair(LLONG_MAX/,-);
else
second=make_pair(,-);
} if(type==)
{
for(int i=head[x];i!=-;i=edg[i].next)
{
int v=edg[i].v;
if(v==fa)continue; if(v==second.second)dfs(v,x,,max(last_ans,-first.first)+value[x]);
else
dfs(v,x,,max(last_ans,-second.first)+value[x]);
}
}
else
{
ans=max(ans,min(last_ans,second.first)+value[x]);
for(int i=head[x];i!=-;i=edg[i].next)
{
int v=edg[i].v;
if(v==fa)continue; if(v==second.second)dfs(v,x,,min(last_ans,first.first)+value[x]);
else
dfs(v,x,,min(last_ans,second.first)+value[x]);
}
}
} int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
init(n); for(int i=;i<=n;i++)
scanf("%lld",&value[i]); for(int i=;i<=n;i++)
{
long long a;
scanf("%lld",&a);
value[i]-=a;
} for(int i=;i<n;i++)
{
int u,v;
scanf("%d %d",&u,&v);
addedge(u,v);
addedge(v,u);
} /* if(n<=2)
{
long long sum=0;
for(int i=1;i<=n;i++)sum+=value[i];
printf("%lld\n",sum);
continue;
}*/ dfs(,-,,LLONG_MIN/);
dfs(,-,,LLONG_MAX/); printf("%lld\n",ans);
}
return ;
}
Acesrc and Travel的更多相关文章
- HDU 6662 Acesrc and Travel (换根dp)
Problem Description Acesrc is a famous tourist at Nanjing University second to none. During this sum ...
- 2019杭电多校 hdu6662 Acesrc and Travel (树形dp
http://acm.hdu.edu.cn/showproblem.php?pid=6662 题意:有两个人在树上博弈,每个点节点有两个分数a[i]和b[i],先手先选择一个点,后手在先手选的点的相邻 ...
- Acesrc and Travel(2019年杭电多校第八场06+HDU6662+换根dp)
题目链接 传送门 题意 两个绝顶聪明的人在树上玩博弈,规则是轮流选择下一个要到达的点,每达到一个点时,先手和后手分别获得\(a_i,b_i\)(到达这个点时两个人都会获得)的权值,已经经过的点无法再次 ...
- HDU 6662 Acesrc and Travel 换根DP,宇宙最傻记录
#include<bits/stdc++.h> typedef long long ll; using namespace std; const int maxn=1e6+50; cons ...
- 2019 Multi-University Training Contest 8 - 1006 - Acesrc and Travel - 树形dp
http://acm.hdu.edu.cn/showproblem.php?pid=6662 仿照 CC B - TREE 那道题的思路写的,差不多.也是要走路径. 像这两种必须走到叶子的路径感觉是必 ...
- 【HDOJ6662】Acesrc and Travel(树形DP,换根)
题意:有一棵n个点的树,每个点上有两个值a[i],b[i] A和B在树上行动,A到达i能得到a[i]的偷税值,B能得到b[i],每次行动只能选择相邻的点作为目标 两个人都想最大化自己的偷税值和对方的差 ...
- 【HDU6662】Acesrc and Travel【树形DP】
题目大意:给你一棵树,每个节点有一个权值,Alice和Bob进行博弈,起点由Alice确定,确定后交替选择下一个点,Alice目标是最终值尽可能大,Bob目标是尽可能小 题解:很明显是树形DP,那么考 ...
- 【HDU6662】Acesrc and Travel(树型Dp)
题目链接 大意 给出一颗树,每个点上有一个权值\(A[i]\),有两个绝顶聪明的人甲和乙. 甲乙两人一起在树上轮流走,不能走之前经过的点.(甲乙时刻在一起) 甲先手,并可以确定起点.甲想要走过的点权之 ...
- 2019DX#8
Solved Pro.ID Title Ratio(Accepted / Submitted) 1001 Acesrc and Cube Hypernet 7.32%(3/41) 1002 A ...
随机推荐
- 深夜Python - 第2夜 - 爬行
深夜Python - 第2夜 - 爬行 我曾经幻想自己是一只蜗牛,有自己的一只小壳,不怕风,不怕雨,浪荡江湖,游历四方……夜猫兄一如既往地打断了我不切实际的幻想:“浪荡?游历?等你退休了都爬不出家门口 ...
- Python Fabric模块详解
Python Fabric模块详解 什么是Fabric? 简单介绍一下: Fabric是一个Python的库和命令行工具,用来提高基于SSH的应用部署和系统管理效率. 再具体点介绍一下,Fabri ...
- 2019 Multi-University Training Contest 6 Nonsense Time (纯暴力)
题意:给你一个n的排列,起初这些数都不能用, 然后还有一个数组 第 i 个数表示下标为 i 的数能够使用. 问每一个 i 对应的最长上升子序列. 题解: 可以通过倒推,从后往前考虑转化一下 ,然后就是 ...
- LOJ#6075. 「2017 山东一轮集训 Day6」重建
题目描述: 给定一个 n个点m 条边的带权无向连通图 ,以及一个大小为k 的关键点集合S .有个人要从点s走到点t,现在可以对所有边加上一个非负整数a,问最大的a,使得加上a后,满足:s到t的最短路长 ...
- Python全栈开发:web框架
Web框架本质 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1 ...
- [JZOJ4682] 【GDOI2017模拟8.11】生物学家
题目 描述 题目大意 有一个010101序列,可以改变状态,每个状态改变都有固定的代价. 接下来有些人想要将一些位置改成特定的状态,如果按照他们要求做了就可以得到一些钱, 否则得不到,有时还要陪钱. ...
- [JZOJ3167] 【GDOI2013模拟3】查税
题目 描述 题目大意 维护一个有一次函数组成的序列 具体来说,对于位置xxx,现在的值为sx+zx∗(T−tx)s_x+z_x*(T-t_x)sx+zx∗(T−tx) 有两个操作,修改某个位置上 ...
- 要原版 jdk-6u14-windows-i586.exe
http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase6-419409.html#j ...
- day 36 MySQL的库、表的详细操作
MySQL的库.表的详细操作 MySQL数据库 本节目录 一 库操作 二 表操作 三 行操作 一 库操作 1.创建数据库 1.1 语法 CREATE DATABASE 数据库名 charset u ...
- eval(str)函数
转载:地址于http://blog.csdn.net/SeeTheWorld518/article/details/47983511 eval(str)函数很强大,官方解释为:将字符串str当成有效的 ...