题目:https://codeforc.es/gym/101810/problem/M

题意:给 你一颗树,下面有m次查询,求u->v的最大值是多少,输入两点之间都会有两条边,正边有正权,反边有反权,然后问u->v可以经过的最大权值是多少

思路:我们首先以u为根我们会发现我们走非v所在子树时我们都可以把所有边走完并且回来,对于v所在子树我们也可以把正反两条边都走完,u-v的最短的那条路只能走一遍,所以这个问题就转化为了求最长链问题,u->v的最长链,但是我们有m次查询,我们不可能每次取遍历所有的点来找最长链,我们其实可以以1为根,然后用两个数组分别记录 当前点到根的距离的正反权,然后自己画图能够看出两点的距离其实就是   dis1[u]-dis1[lca(u,v)]  +  dis2[v]-dis2[lca(u,v)]

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define mst(ss,b) memset((ss),(b),sizeof(ss))
  4. const int N = 1e5+;
  5. int t,n,m,dis[N],dis1[N],fa[N][],fa1[N][],dep[N],dep1[N],vs[N],vs1[N];
  6. struct nd{
  7. int to,w,w1;
  8. };
  9. vector<nd> g[N];
  10.  
  11. void init() {
  12. for(int i=;i<=n;i++) g[i].clear();
  13. mst(dis,),mst(fa,),mst(dep,),mst(vs,);
  14. mst(dis1,),mst(fa1,),mst(dep1,),mst(vs1,);
  15. }
  16.  
  17. void dfs(int x) {///求出每个节点到根节点的距离、深度、父亲
  18. vs[x]=;
  19. for(int i=;i<g[x].size();i++) {
  20. nd tp=g[x][i];
  21. int v=tp.to,w=tp.w,w1=tp.w1;
  22. if(vs[v]) continue;
  23. fa[v][]=x;
  24. fa1[v][]=x;
  25. dis[v]=dis[x]+w;
  26. dis1[v]=dis1[x]+w1;
  27. dep[v]=dep[x]+;
  28. dep1[v]=dep1[x]+;
  29. dfs(v);
  30. }
  31. }
  32.  
  33. void bz() {///倍增预处理
  34. for(int j=;j<;j++)///fa[i][j]表示结点 i 的第2^j个祖先
  35. for(int i=;i<=n;i++)
  36. fa[i][j]=fa[fa[i][j-]][j-],
  37. fa1[i][j]=fa1[fa1[i][j-]][j-];
  38. }
  39.  
  40. int lca(int u,int v) {
  41. if(dep[u]<dep[v]) swap(u,v);///注意是交换u和v,不是交换dep[u]和dep[v]
  42. int d=dep[u]-dep[v];
  43. for(int i=;i<;i++)///先调整到同一深度
  44. if(d&(<<i)) u=fa[u][i];
  45. if(u==v) return u;
  46. for(int i=;i>=;i--) {///注意是倒着for,二进制拆分,从大到小尝试
  47. if(fa[u][i]!=fa[v][i]) {
  48. u=fa[u][i];
  49. v=fa[v][i];
  50. }
  51. }
  52. return fa[u][];
  53. }
  54.  
  55. int main() {
  56. while(~scanf("%d",&t)) {
  57. while(t--) {
  58. scanf("%d",&n);
  59. init();
  60. long long ans = ;
  61. for(int i=;i<n;i++) {
  62. int a,b,c,d;
  63. scanf("%d%d%d%d",&a,&b,&c,&d);
  64. g[a].push_back({b,c,d});
  65. g[b].push_back({a,d,c});
  66. ans += c+d;
  67. }
  68. dep[]=,dis[]=;
  69. dep1[]=,dis1[]=;
  70. dfs();
  71. bz();
  72. scanf("%d",&m);
  73. for(int i=;i<=m;i++) {
  74. int u,v;
  75. scanf("%d%d",&u,&v);
  76. printf("%lld\n",ans-(dis1[v]-dis1[lca(u,v)]+dis[u]-dis[lca(u,v)]));
  77. }
  78. }
  79. }
  80. return ;
  81. }

gym 101810 M. Greedy Pirate (LCA)的更多相关文章

  1. GYM101810 ACM International Collegiate Programming Contest, Amman Collegiate Programming Contest (2018) M. Greedy Pirate (LCA)

    题意:有\(n\)个点,\(n-1\)条边,每条边正向和反向有两个权值,且每条边最多只能走两次,有\(m\)次询问,问你从\(u\)走到\(v\)的最大权值是多少. 题解:可以先在纸上画一画,不难发现 ...

  2. codeforces gym #101161E - ACM Tax(lca+主席树)

    题目链接: http://codeforces.com/gym/101161/attachments 题意: 给出节点数为$n$的树 有$q$次询问,输出$a$节点到$b$节点路程中,经过的边的中位数 ...

  3. Codeforces Gym 100015C City Driving 离线LCA

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

  4. Gym 101810

    友情提示: 这篇题解并没有GJKL,因为我也不会,而且看别人代码也看不懂,而且问学长还不给我讲!hmc:这个题巨麻烦,我只能说balabala.我不学了我退役了啊! A:这傻逼题我从开头wa了四个小时 ...

  5. gym 101889I Imperial roads 最小生成树+LCA

    题目传送门 题意: 给出一幅无向带权图,q次询问,每次询问都求一棵包含给出的边的最小生成树. 思路: 首先求出最小生成树(kruskal),如果查询的边在最小生成树上,肯定是直接输出最小生成树,如果不 ...

  6. Gym - 101810H ACM International Collegiate Programming Contest (2018)

    bryce1010模板 http://codeforces.com/gym/101810 #include <bits/stdc++.h> using namespace std; #de ...

  7. Gym - 101810F ACM International Collegiate Programming Contest (2018)

    bryce1010模板 http://codeforces.com/gym/101810 #include<bits/stdc++.h> using namespace std; #def ...

  8. Gym - 101810E ACM International Collegiate Programming Contest (2018)

    bryce1010模板 http://codeforces.com/gym/101810 #include<bits/stdc++.h> using namespace std; #def ...

  9. Gym - 101810D ACM International Collegiate Programming Contest (2018)

    bryce1010模板 http://codeforces.com/gym/101810 #include <bits/stdc++.h> using namespace std; #de ...

随机推荐

  1. ping局域网主机得到外网IP或另一网段IP

    症状::两个笔记本连接到同一个路由器上, 一个ip是 192.168.1.100,主机名是Lenovo-A, 另一个是192.168.1.109,主机名是Lenovo-B 在Lenovo-A 上pin ...

  2. [暑假集训Day4T1]羊圈

    ZYC同志开农场了????? 二分答案. 对于每一个二分出来的答案对其进行检查(check),检查是否有一个长度大于m的字段和的平均值大于mid.方法如下:先把原数组的每一个元素减去mid,储存进一个 ...

  3. Centos7.6替换自带的jre安装jdk

    Centos7.6自带jre 1.8,可以作为java运行环境.但如果要编译java程序那就需要jdk,以下介绍如何把自带的jre卸掉并安装jdk 首先要卸载自带的jre PS:由于不同版本的操作系统 ...

  4. 阿里云云监控agent插件 - Linux版

    阿里云云监控agent插件使用指南 1.安装(注意,要以“root”权限运行,复制 sudo后面的就行,别把#也复制进去) #64位 # sudo bash -c "wget -e 'htt ...

  5. 【学习总结】Python-3-Python数字类型转换

    菜鸟教程-Python3-Python数字 Python3支持三种数值类型:整型int,浮点型float,复数complex 格式:将数字类型作为函数名即可,然后传入要转换的参数. int(x) 将x ...

  6. 软件工程第六组U-Helpβ版使用说明

    软件工程第六组U-Helpβ版使用说明 U-help ——告别取件烦恼 produced by 六扇门 源代码下载地址:https://github.com/U-Help/Version-1.0 安装 ...

  7. 英伟达GPU 嵌入式开发平台

    英伟达GPU  嵌入式开发平台 1.         JETSON TX1 开发者组件 JETSON TX1 开发者组件是视觉计算的全功能 开发平台,旨在让您能够快速地安装和运行. 该组件带有 Lin ...

  8. 从零开始的PHP生活Day1

    PHP 什么是PHP? PHP(Hypertext Preprocessor,超文本预处理器)是一种服务器端的.跨平台的.HTML嵌入式的弱类型开源脚本语言. 1.服务器端:PHP需要使用服务器软件进 ...

  9. React(5) --绑定函数事件

    绑定函数事件 在以类继承的方式定义的组件中,为了能方便地调用当前组件的其他成员方法或属性(如:this.state),通常需要将事件处理函数运行时的 this 指向当前组件实例. run(){     ...

  10. python发行包 IDE

    https://blog.csdn.net/qq_38188725/article/details/80624004 https://blog.csdn.net/qq_38188725/article ...