原文链接https://www.cnblogs.com/zhouzhendong/p/9246484.html

题目传送门 - Codeforces 1000G Two-Paths

题意

  给定一棵有 $n(2\leq n\leq 3\times 10^5)$ 个节点的树,其中节点 $i$ 有权值 $a_i$,边 $e$ 有权值 $w_e$。$(1\leq a_i,w_e\leq 10^9)$

  现在给出 $q(1\leq q\leq 4\times 10^5)$ 组询问,每组询问给定两个数 $x,y(1\leq x,y\leq n)$。

  如果一条路径的起点和终点分别为 $x$ 和 $y$,而且这条路径重复经过同一条边最多 $2$ 次(点可以多次经过),那么这条路径合法。

  一条合法路径 $P$ 的价值为 $Pr(p)$。$\text{Pr}(p) = \sum\limits_{v \in \text{distinct vertices in } p}{a_v} - \sum\limits_{e \in \text{distinct edges in } p}{k_e \cdot w_e}$。

  其中 $k_e$ 为路径 $p$ 经过 $e$ 的次数。

  每次询问问所有合法路径的最大价值。

题解

  我们来跑一下树形dp。

  求出以下值。(下面是示意图,有填色的部分表示被计算)

  其中 $dp1,dp2,f1,sum$ 都表示所取的部分的合法最大值。

  

    

  

  再描述一下上面六个量的意义:

  dp1[x]:往 $x$ 的后代节点走最多可以赚多少。

  dp2[x]:往 $x$ 的祖先走最多可以赚多少。

  f1[x]:从 $x$ 的祖先向 $x$ 走最多可以赚多少。

  sum[x]:令树根到 $x$ 父亲的链为主链,假设主链上行走没有任何消耗和获益,向主链走最多可以获益多少。

  len[x]:$x$ 到根的距离(带边权)。

  s[x]:$x$ 的深度。

  

  在回答询问 $x,y$ 的时候,首先从 $x$ 到 $y$ 的路径一定被选,其中的边一定只走一次。

  其他的我们根据之前维护的量分类讨论加加减减一下就可以了。

  详见代码。

代码

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long LL;
  4. const int N=300005,M=N*2;
  5. LL read(){
  6. LL x=0;
  7. char ch=getchar();
  8. while (!('0'<=ch&&ch<='9'))
  9. ch=getchar();
  10. while ('0'<=ch&&ch<='9')
  11. x=x*10+ch-48,ch=getchar();
  12. return x;
  13. }
  14. struct Gragh{
  15. int cnt,y[M],nxt[M],fst[N];
  16. LL z[M];
  17. void clear(){
  18. cnt=0;
  19. memset(fst,0,sizeof fst);
  20. }
  21. void add(int a,int b,LL c){
  22. y[++cnt]=b,z[cnt]=c,nxt[cnt]=fst[a],fst[a]=cnt;
  23. }
  24. }g;
  25. int n,q,fa[N][20],depth[N],xx,yy;
  26. LL a[N],dp1[N],f1[N],dp2[N],sum[N],fadis[N],len[N],s[N];
  27. void dfs1(int x,int pre,int d,LL L){
  28. fa[x][0]=pre;
  29. depth[x]=d;
  30. len[x]=L;
  31. s[x]=s[pre]+a[x];
  32. for (int i=1;i<20;i++)
  33. fa[x][i]=fa[fa[x][i-1]][i-1];
  34. dp1[x]=0;
  35. for (int i=g.fst[x];i;i=g.nxt[i]){
  36. int y=g.y[i];
  37. LL z=g.z[i];
  38. if (y!=pre){
  39. dfs1(y,x,d+1,L+z);
  40. fadis[y]=z;
  41. f1[y]=max(dp1[y]+a[y]-z*2,0LL);
  42. dp1[x]+=f1[y];
  43. }
  44. }
  45. }
  46. void dfs2(int x,int pre,LL v,LL v2){
  47. dp2[x]=v;
  48. sum[x]=v2;
  49. for (int i=g.fst[x];i;i=g.nxt[i]){
  50. int y=g.y[i];
  51. LL z=g.z[i];
  52. if (y!=pre){
  53. LL _v=max(v+a[x]+dp1[x]-f1[y]-2*z,0LL);
  54. LL _v2=max(v2+dp1[x]-f1[y],0LL);
  55. dfs2(y,x,_v,_v2);
  56. }
  57. }
  58. }
  59. int LCA(int x,int y){
  60. if (depth[x]<depth[y])
  61. swap(x,y);
  62. for (int i=19;i>=0;i--)
  63. if (depth[x]-(1<<i)>=depth[y])
  64. x=fa[x][i];
  65. if (x==y)
  66. return x;
  67. for (int i=19;i>=0;i--)
  68. if (fa[x][i]!=fa[y][i])
  69. x=fa[x][i],y=fa[y][i];
  70. xx=x,yy=y;
  71. return fa[x][0];
  72. }
  73. int main(){
  74. scanf("%d%d",&n,&q);
  75. for (int i=1;i<=n;i++)
  76. a[i]=read();
  77. g.clear();
  78. for (int i=1;i<n;i++){
  79. int a=read(),b=read();
  80. LL c=read();
  81. g.add(a,b,c);
  82. g.add(b,a,c);
  83. }
  84. dfs1(1,0,0,0);
  85. dfs2(1,0,0,0);
  86. while (q--){
  87. int x,y,lca;
  88. scanf("%d%d",&x,&y);
  89. if (depth[x]>depth[y])
  90. swap(x,y);
  91. lca=LCA(x,y);
  92. if (x==lca){
  93. if (y==lca){
  94. printf("%I64d\n",dp1[x]+dp2[x]+a[x]);
  95. continue;
  96. }
  97. LL ans=s[y]-s[x]+a[x];
  98. ans-=len[y]-len[x];
  99. ans+=sum[y]-sum[x];
  100. ans+=dp2[x]+dp1[y];
  101. printf("%I64d\n",ans);
  102. continue;
  103. }
  104. LL ans=s[x]+s[y]-s[lca]*2+a[lca];
  105. ans-=len[x]+len[y]-len[lca]*2;
  106. ans+=sum[x]+sum[y]-sum[xx]-sum[yy];
  107. ans+=dp1[lca]-f1[xx]-f1[yy];
  108. ans+=dp2[lca]+dp1[x]+dp1[y];
  109. printf("%I64d\n",ans);
  110. }
  111. return 0;
  112. }

  

Codeforces 1000G Two-Paths 树形动态规划 LCA的更多相关文章

  1. 蓝桥杯 ALGO-4 结点选择 (树形动态规划)

    问题描述 有一棵 n 个节点的树,树上每个节点都有一个正整数权值.如果一个点被选择了,那么在树上和它相邻的点都不能被选择.求选出的点的权值和最大是多少? 输入格式 第一行包含一个整数 n . 接下来的 ...

  2. 树形动态规划(树状DP)小结

    树状动态规划定义 之所以这样命名树规,是因为树形DP的这一特殊性:没有环,dfs是不会重复,而且具有明显而又严格的层数关系.利用这一特性,我们可以很清晰地根据题目写出一个在树(型结构)上的记忆化搜索的 ...

  3. Codeforces 581F Zublicanes and Mumocrates - 树形动态规划

    It's election time in Berland. The favorites are of course parties of zublicanes and mumocrates. The ...

  4. Codeforces Beta Round #14 (Div. 2) D. Two Paths 树形dp

    D. Two Paths 题目连接: http://codeforces.com/contest/14/problem/D Description As you know, Bob's brother ...

  5. Codeforces 839C Journey - 树形动态规划 - 数学期望

    There are n cities and n - 1 roads in the Seven Kingdoms, each road connects two cities and we can r ...

  6. Codeforces Round #343 (Div. 2) E. Famil Door and Roads (树形dp,lca)

    Famil Door's City map looks like a tree (undirected connected acyclic graph) so other people call it ...

  7. LEETCODE —— Unique Paths II [动态规划 Dynamic Programming]

    唯一路径问题II Unique Paths II Follow up for "Unique Paths": Now consider if some obstacles are ...

  8. Codeforces Gym 100015C City Driving 离线LCA

    City Driving 题目连接: http://codeforces.com/gym/100015/attachments Description You recently started fre ...

  9. 【ACM/ICPC2013】树形动态规划专题

    前言:按照计划,昨天应该是完成树形DP7题和二分图.最大流基础专题,但是由于我智商实在拙计,一直在理解树形DP的思想,所以第二个专题只能顺延到今天了.但是昨天把树形DP弄了个5成懂我是很高兴的!下面我 ...

随机推荐

  1. 关于EditText一些效果

    效果如图,由TextView  View(竖线) EditText与ImageView组成 首先更改draw able中shape代码 <?xml version="1.0" ...

  2. log4net 全局配置

    public class LogHelper { private static readonly log4net.ILog ILogInfo = log4net.LogManager.GetLogge ...

  3. 自然语言处理之关键词提取TF-IDF

    统计每篇文章重要的词作为这篇文章的关键词,用tf-idf来实现.生产中有很多第三包可以调用,这里记录原理,顺便熟练python 1.公式 : 计算词频TF 考虑到文章有长短之分,为了便于不同文章的比较 ...

  4. (转)浅谈Hybrid技术的设计与实现

    转载地址:https://www.cnblogs.com/yexiaochai/p/4921635.html 前言 浅谈Hybrid技术的设计与实现 浅谈Hybrid技术的设计与实现第二弹 浅谈Hyb ...

  5. Android 应用防止被二次打包指南

    前言 “Android APP二次打包”则是盗版正规Android APP,破解后植入恶意代码重新打包.不管从性能.用户体验.外观它都跟正规APP一模一样但是背后它确悄悄运行着可怕的程序,它会在不知不 ...

  6. 高并发编程基础(java.util.concurrent包常见类基础)

    JDK5中添加了新的java.util.concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能.因为同步容器将所有对容器状态的访问都串行化了,这样保证了线程的安全性,所以这种方法 ...

  7. java----String解析

    String在内存中的分析: public class Demo { public static void main(String[] args){ String a = new String(&qu ...

  8. 右键菜单添加打开CMD选项

    转载: https://www.cnblogs.com/mkdd/p/8649139.html#undefined 目前用的win7sp1系统,平时打开CMD窗口通常用三种方法:1.win+R然后输入 ...

  9. Python游戏编程(Pygame)

    安装Pygame pip install pygame C:\Users> pip install pygame Collecting pygame Downloading https://fi ...

  10. 阿里云人脸识别测试接口出错 返回Body:{ "errno": 1031, "err_msg": "Invalid Image URL.", "request_id": "cdbe2927-e1bb-4eb1-a603-8fcd4b0b7fc8" }

    错误信息如下 返回Body:{ "errno": 1031, "err_msg": "Invalid Image URL.", " ...