像树的直径一样,两个集合的最长路也是由两个集合内部的最长路的两个端点组成的,于是我们知道了两个集合的最长路,枚举一下两两端点算出答案就可以合并了,所以就可以用线段树维护一个区间里的最长路了。

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdlib>
  4. #include<cstdio>
  5. #include<cmath>
  6. #include<algorithm>
  7. #define ll long long
  8. using namespace std;
  9. const int maxn=,inf=1e9;
  10. struct tjm{int too,dis,pre;}e[maxn];
  11. struct poi{int p[];ll dis;}tree[maxn<<];
  12. int n,m,a,b,x,y,z,tot;
  13. int d[maxn],son[maxn],size[maxn],fa[maxn],top[maxn],last[maxn];
  14. ll dep[maxn];
  15. inline void read(int &k)
  16. {
  17. int f=;k=;char c=getchar();
  18. while(c<''||c>'')c=='-'&&(f=-),c=getchar();
  19. while(c<=''&&c>='')k=k*+c-'',c=getchar();
  20. k*=f;
  21. }
  22. void add(int x,int y,int z){e[++tot].too=y;e[tot].dis=z;e[tot].pre=last[x];last[x]=tot;}
  23. void dfs1(int x)
  24. {
  25. size[x]=;d[x]=d[fa[x]]+;
  26. for(int i=last[x],too=e[i].too;i;i=e[i].pre,too=e[i].too)
  27. if(too!=fa[x])
  28. {
  29. dep[too]=dep[x]+e[i].dis;
  30. fa[too]=x;dfs1(too);
  31. size[x]+=size[too];
  32. if(size[too]>size[son[x]])son[x]=too;
  33. }
  34. }
  35. void dfs2(int x,int tp)
  36. {
  37. top[x]=tp;
  38. if(son[x])dfs2(son[x],tp);
  39. for(int i=last[x],too=e[i].too;i;i=e[i].pre,too=e[i].too)
  40. if(too!=fa[x]&&too!=son[x])dfs2(too,too);
  41. }
  42. int lca(int x,int y)
  43. {
  44. int f1=top[x],f2=top[y];
  45. while(f1!=f2)
  46. {
  47. if(d[f1]<d[f2])swap(x,y),swap(f1,f2);
  48. x=fa[f1];f1=top[x];
  49. }
  50. if(d[x]<d[y])swap(x,y);
  51. return y;
  52. }
  53. void pushup(poi x,poi y,ll &dist,int &p1,int &p2)
  54. {
  55. if(x.dis>y.dis)dist=x.dis,p1=x.p[],p2=x.p[];
  56. else dist=y.dis,p1=y.p[],p2=y.p[];
  57. for(int i=;i<=;i++)
  58. for(int j=;j<=;j++)
  59. if(x.p[i]&&y.p[j])
  60. {
  61. ll dis=dep[x.p[i]]+dep[y.p[j]]-(dep[lca(x.p[i],y.p[j])]<<);
  62. if(dis>dist)dist=dis,p1=x.p[i],p2=y.p[j];
  63. }
  64. }
  65. void build(int x,int l,int r)
  66. {
  67. if(l==r){tree[x].p[]=tree[x].p[]=l;return;}
  68. int mid=(l+r)>>;
  69. build(x<<,l,mid);build(x<<|,mid+,r);
  70. pushup(tree[x<<],tree[x<<|],tree[x].dis,tree[x].p[],tree[x].p[]);
  71. }
  72. void query(int x,int l,int r,int cl,int cr,ll &dis,int &p1,int &p2)
  73. {
  74. if(cl<=l&&r<=cr){dis=tree[x].dis;p1=tree[x].p[];p2=tree[x].p[];return;}
  75. int mid=(l+r)>>;
  76. poi t1,t2;t1.dis=t2.dis=-;t1.p[]=t1.p[]=t2.p[]=t2.p[]=;
  77. if(cl<=mid)query(x<<,l,mid,cl,cr,t1.dis,t1.p[],t1.p[]);
  78. if(cr>mid)query(x<<|,mid+,r,cl,cr,t2.dis,t2.p[],t2.p[]);
  79. pushup(t1,t2,dis,p1,p2);
  80. }
  81. int main()
  82. {
  83. read(n);
  84. for(int i=;i<n;i++)read(x),read(y),read(z),add(x,y,z),add(y,x,z);
  85. dfs1();dfs2(,);
  86. build(,,n);
  87. read(m);
  88. for(int i=;i<=m;i++)
  89. {
  90. read(a),read(b),read(x),read(y);
  91. poi t1,t2;t1.dis=t2.dis=t1.p[]=t1.p[]=t2.p[]=t2.p[]=;ll dis;int p1,p2;
  92. query(,,n,a,b,dis,t1.p[],t1.p[]);query(,,n,x,y,dis,t2.p[],t2.p[]);
  93. pushup(t1,t2,dis,p1,p2);
  94. printf("%lld\n",dis);
  95. }
  96. }

51nod 1766 树上的最远点对(线段树)的更多相关文章

  1. 51nod 1766 树上的最远点对——线段树

    n个点被n-1条边连接成了一颗树,给出a~b和c~d两个区间,表示点的标号请你求出两个区间内各选一点之间的最大距离,即你需要求出max{dis(i,j) |a<=i<=b,c<=j& ...

  2. 51 nod 1766 树上的最远点对(线段树+lca)

    1766 树上的最远点对 基准时间限制:3 秒 空间限制:524288 KB 分值: 80 难度:5级算法题   n个点被n-1条边连接成了一颗树,给出a~b和c~d两个区间,表示点的标号请你求出两个 ...

  3. 51nod 1766 树上的最远点对 | LCA ST表 线段树 树的直径

    51nod 1766 树上的最远点对 | LCA ST表 线段树 树的直径 题面 n个点被n-1条边连接成了一颗树,给出a~b和c~d两个区间,表示点的标号请你求出两个区间内各选一点之间的最大距离,即 ...

  4. [51nod 1766]树上的最远点对 (树的直径+ST表求lca+线段树)

    [51nod 1766]树上的最远点对 (树的直径+ST表求lca+线段树) 题面 给出一棵N个点的树,Q次询问一点编号在区间[l1,r1]内,另一点编号在区间[l2,r2]内的所有点对距离最大值.\ ...

  5. 51Nod 1766 树上的最远点对

    Description 一棵树,询问两个端点编号分别在在 \([a,b]\) 和 \([c,d]\) 两个区间中的最长链. Sol 线段树+ST表. 树上最长链可以合并,只需要合并两个区间最长链的两个 ...

  6. 【树形结构】51nod 1766 树上的最远点对

    题目内容 \(n\)个点被\(n−1\)条边连接成了一颗树,边有权值\(w_i\).有\(q\)个询问,给出\([a,b]\)和\([c,d]\)两个区间,表示点的标号请你求出两个区间内各选一点之间的 ...

  7. 【51nod】1766 树上的最远点对

    [题意]给定n个点的树,m次求[a,b]和[c,d]中各选出一个点的最大距离.abcd是标号区间,n,m<=10^5 [算法]LCA+树的直径理论+线段树 [题解] 树的直径性质:距离树上任意点 ...

  8. 51Nod.1766.树上最远点对(树的直径 RMQ 线段树/ST表)

    题目链接 \(Description\) 给定一棵树.每次询问给定\(a\sim b,c\sim d\)两个下标区间,从这两个区间中各取一个点,使得这两个点距离最远.输出最远距离. \(n,q\leq ...

  9. csu 1798(树上最远点对,线段树+lca)

    1798: 小Z的城市 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 60  Solved: 16[Submit][Status][Web Board] ...

随机推荐

  1. Python接口测试实战4(上) - 接口测试框架实战

    如有任何学习问题,可以添加作者微信:lockingfree 课程目录 Python接口测试实战1(上)- 接口测试理论 Python接口测试实战1(下)- 接口测试工具的使用 Python接口测试实战 ...

  2. Mysql基础操作语句

    SQL 简单的增删改查 不区分大小写, 表名和字段名可不加引号 查询语句 SELECT * FROM `table_name`; -- 注释 CTRL+/ : 注释 CTRL+/ : 取消注释 /* ...

  3. jvm之对象创建过程

    常量池中定位类的符号引用                ↓ 检查符号引用所代表的类是否已被加载,解析和初始化过  →                 ↓                        ...

  4. java之接口开发-初级篇-socket通信

    socket通信实现util包类实现 public class SocketThread extends Thread { public void run() { while (true) { // ...

  5. 使用Scrapy构建一个网络爬虫

    记得n年前项目需要一个灵活的爬虫工具,就组织了一个小团队用Java实现了一个爬虫框架,可以根据目标网站的结构.地址和需要的内容,做简单的配置开发,即可实现特定网站的爬虫功能.因为要考虑到各种特殊情形, ...

  6. Karen and Coffee CF 816B(前缀和)

    Description To stay woke and attentive(专注的) during classes, Karen needs some coffee! Karen, a coffee ...

  7. 20162316刘诚昊 第八周实验报告:实验二 Java面向对象程序设计

    实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 实验要求 1.没有Linux基础的同学建议先学习<L ...

  8. 关于cnblog.com的用户体验

    首先我自己目前是一个学生党,每天在博客园上就上发布一些自己做的东西以及老师布置的作业,还能在上面学习很多别人的一些好的列子,我就希望博客园能够很好地为我们这些学生服务,当我们用它时能够很好地达到我们的 ...

  9. mysql hql异常

    org.springframework.dao.InvalidDataAccessResourceUsageException:  could not execute query; nested ex ...

  10. 《我是一只it小小鸟》观后感

    在这个学期开始的时候我们的老师推荐给我们这本书.在很多的网站上只要一提到IT,总会有人推荐这本书,我在读这本书之前看了很多关于它的书评,其中有一位网友的一句话让我对它产生了很大的兴趣:“印象最深的是书 ...