题意:有一棵n个点的树,每个点上有两个值a[i],b[i]

A和B在树上行动,A到达i能得到a[i]的偷税值,B能得到b[i],每次行动只能选择相邻的点作为目标

两个人都想最大化自己的偷税值和对方的差,都按最优策略行动,不能走已经走过的点,行动直到没有点可走为止

A可以选择任意出发点,然后B开始走,然后A开始走……

n<=1e5,0<=a[i],b[i]<=1e9

思路:

f[u][0]表示从u出发下一步走儿子的min,f[u][1]表示max

g[u][0]表示从u出发下一步走父亲的min,g[u][1]表示max

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> Pll;
typedef vector<int> VI;
typedef vector<PII> VII;
//typedef pair<ll,ll>P;
#define N 1000010
#define M 200010
#define fi first
#define se second
#define MP make_pair
#define pb push_back
#define pi acos(-1)
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
#define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
#define lowbit(x) x&(-x)
#define Rand (rand()*(1<<16)+rand())
#define id(x) ((x)<=B?(x):m-n/(x)+1)
#define ls p<<1
#define rs p<<1|1 const int MOD=1e9+,inv2=(MOD+)/;
double eps=1e-;
int INF=1e9;
int inf=0x7fffffff;
int dx[]={-,,,};
int dy[]={,,-,}; ll f[N][],g[N][];
ll t1[N],t2[N],t3[N],t4[N],t5[N],t6[N],a[N],b[N];
int head[N],vet[N],nxt[N],d[N],tot; int read()
{
int v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} void add(int a,int b)
{
nxt[++tot]=head[a];
vet[tot]=b;
head[a]=tot;
} void dfs1(int u,int fa)
{
int e=head[u],s=;
ll t1=INF,t2=-INF;
while(e)
{
int v=vet[e];
if(v!=fa)
{
s++;
dfs1(v,u);
t1=min(t1,f[v][]);
t2=max(t2,f[v][]);
}
e=nxt[e];
}
if(s)
{
f[u][]=t1+a[u]-b[u];
f[u][]=t2+a[u]-b[u];
}
else f[u][]=f[u][]=a[u]-b[u];
} void dfs2(int u,int fa)
{
int s=;
int e=head[u];
while(e)
{
int v=vet[e];
if(v!=fa)
{
s++;
t1[s]=f[v][];
t2[s]=f[v][];
}
e=nxt[e];
}
t3[]=t1[];
rep(i,,s) t3[i]=max(t3[i-],t1[i]);
t4[s]=t1[s];
per(i,s-,) t4[i]=max(t4[i+],t1[i]);
t5[]=t2[];
rep(i,,s) t5[i]=min(t5[i-],t2[i]);
t6[s]=t2[s];
per(i,s-,) t6[i]=min(t6[i+],t2[i]);
e=head[u];
int i=;
while(e)
{
int v=vet[e];
if(v!=fa)
{
i++;
ll t=g[u][];
ll t0=-INF;
if(i->=) t0=max(t0,t3[i-]+a[u]-b[u]);
if(i+<=s) t0=max(t0,t4[i+]+a[u]-b[u]);
if(u==&&s>) t=t0;
else t=max(t,t0);
g[v][]=a[v]-b[v]+t;
t=g[u][];
t0=INF;
if(i->=) t0=min(t0,t5[i-]+a[u]-b[u]);
if(i+<=s) t0=min(t0,t6[i+]+a[u]-b[u]);
if(u==&&s>) t=t0;
else t=min(t,t0);
g[v][]=a[v]-b[v]+t;
}
e=nxt[e];
}
e=head[u];
while(e)
{
int v=vet[e];
if(v!=fa) dfs2(v,u);
e=nxt[e];
}
} int main()
{
//freopen("1.in","r",stdin);
int cas;
scanf("%d",&cas);
while(cas--)
{
int n=read();
rep(i,,n) a[i]=read();
rep(i,,n) b[i]=read();
rep(i,,n) head[i]=d[i]=;
tot=;
rep(i,,n-)
{
int x=read(),y=read();
add(x,y);
add(y,x);
d[x]++; d[y]++;
}
dfs1(,);
g[][]=g[][]=a[]-b[];
dfs2(,);
ll ans=-INF;
rep(i,,n)
{
if(i==) ans=max(ans,f[i][]);
else if(d[i]==) ans=max(ans,g[i][]);
else ans=max(ans,min(f[i][],g[i][]));
}
printf("%I64d\n",ans); } return ;
}

【HDOJ6662】Acesrc and Travel(树形DP,换根)的更多相关文章

  1. bzoj 3743 [Coci2015]Kamp——树形dp+换根

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3743 树形dp+换根. “从根出发又回到根” 减去 “mx ” . 注意dfsx里真的要改那 ...

  2. 树形dp换根,求切断任意边形成的两个子树的直径——hdu6686

    换根dp就是先任取一点为根,预处理出一些信息,然后在第二次dfs过程中进行状态的转移处理 本题难点在于任意割断一条边,求出剩下两棵子树的直径: 设割断的边为(u,v),设down[v]为以v为根的子树 ...

  3. poj3585 Accumulation Degree(树形dp,换根)

    题意: 给你一棵n个顶点的树,有n-1条边,每一条边有一个容量z,表示x点到y点最多能通过z容量的水. 你可以任意选择一个点,然后从这个点倒水,然后水会经过一些边流到叶节点从而流出.问你最多你能倒多少 ...

  4. poj3585 Accumulation Degree[树形DP换根]

    思路其实非常简单,借用一下最大流求法即可...默认以1为根时,$f[x]$表示以$x$为根的子树最大流.转移的话分两种情况,一种由叶子转移,一种由正常孩子转移,判断一下即可.换根的时候由頂向下递推转移 ...

  5. [题解](树形dp/换根)小x游世界树

    2. 小x游世界树 (yggdrasi.pas/c/cpp) [问题描述] 小x得到了一个(不可靠的)小道消息,传说中的神岛阿瓦隆在格陵兰海的某处,据说那里埋藏着亚瑟王的宝藏,这引起了小x的好奇,但当 ...

  6. 2019 Multi-University Training Contest 8 - 1006 - Acesrc and Travel - 树形dp

    http://acm.hdu.edu.cn/showproblem.php?pid=6662 仿照 CC B - TREE 那道题的思路写的,差不多.也是要走路径. 像这两种必须走到叶子的路径感觉是必 ...

  7. 2019ICPC沈阳网络赛-D-Fish eating fruit(树上DP, 换根, 点分治)

    链接: https://nanti.jisuanke.com/t/41403 题意: State Z is a underwater kingdom of the Atlantic Ocean. Th ...

  8. Acwing-287-积蓄程度(树上DP, 换根)

    链接: https://www.acwing.com/problem/content/289/ 题意: 有一个树形的水系,由 N-1 条河道和 N 个交叉点组成. 我们可以把交叉点看作树中的节点,编号 ...

  9. 寒武纪-1005 Travel(树形DP)

    一.题目链接 http://aiiage.hustoj.com/problem.php?id=1005 二.题面 PDF:http://aiiage.hustoj.com/upload/file/20 ...

  10. BZOJ.1576.[Usaco2009 Jan]安全路经Travel(树形DP 并查集)

    题目链接 BZOJ 洛谷 先求最短路树.考虑每一条非树边(u,v,len),设w=LCA(u,v),这条边会对w->v上的点x(x!=w)有dis[u]+dis[v]-dis[x]+len的距离 ...

随机推荐

  1. 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_07 缓冲流_3_BufferedInputStream_字节缓冲

    内容改成abc 来个数组缓冲

  2. 如何减小VMware虚拟机硬盘空间

    VMware是微软出品的目前最好的虚拟机件,利用虚拟机可轻松实现多系统同时运行.特别需要多个系统来完成不同功能的者更是需要,VMware是最好的选择,在这里介绍一些VMware虚拟机使用的小技巧,本文 ...

  3. ora-01033,ORA-16038

    ORA-01033: ORACLE initialization or shutdown in progress 1.进入CMD,执行set ORACLE_SID=fbms,确保连接到正确的SID:2 ...

  4. DataGridView数值列和日期列

    本文转自:http://www.cnblogs.com/conexpress/p/5923324.html 在使用DataGridView编辑数据的时候,编辑的单元格一般会显示为文本框,逻辑值和图片会 ...

  5. 2019_Chrome和ChromeDriver对应关系

    Chrome和ChromeDriver对应关系 ChromeDriver下载地址:http://chromedriver.storage.googleapis.com/index.html Chrom ...

  6. 【SD系列】SAP 创建销售订单-用外部给号的方法步骤

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[SD系列]SAP 创建销售订单-用外部给号的方 ...

  7. (转)http://blog.chinaunix.net/uid-8363656-id-2031644.html CGI 编写

    第一章:基础的基础 回CGI教程目录 1.1 为什么使用CGI?   我没有把什么是CGI放在基础篇的第一段,是因为实在很难说明白到底什么是CGI.而如果你先知道CGI有什么作用,将会很好的理解CGI ...

  8. 排序算法七:基数排序(Radix sort)

    上一篇提到了计数排序,它在输入序列元素的取值范围较小时,表现不俗.但是,现实生活中不总是满足这个条件,比如最大整形数据可以达到231-1,这样就存在2个问题: 1)因为m的值很大,不再满足m=O(n) ...

  9. [Python3] 011 字符串:给你们看看我的内置方法 第三弹

    目录 少废话,上例子 1. encode(encoding='utf-8', errors='strict') 2. expandtabs([tabsize=8]) 借此机会简单地说一说 print( ...

  10. (4.31)quotename函数

    操作sql server尤其是写存储过程时,要用到各种各样的函数,今天就总结一个quotename()的用法. 1.语法: quotename(‘character_string’[,‘quote_c ...