题目描述

如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先。

输入输出格式

输入格式:

第一行包含三个正整数N、M、S,分别表示树的结点个数、询问的个数和树根结点的序号。

接下来N-1行每行包含两个正整数x、y,表示x结点和y结点之间有一条直接连接的边(数据保证可以构成树)。

接下来M行每行包含两个正整数a、b,表示询问a结点和b结点的最近公共祖先。

输出格式:

输出包含M行,每行包含一个正整数,依次为每一个询问的结果。

说明

时空限制:1000ms,128M

数据规模:

对于30%的数据:N<=10,M<=10

对于70%的数据:N<=10000,M<=10000

对于100%的数据:N<=500000,M<=500000

样例说明:

该树结构如下:

第一次询问:2、4的最近公共祖先,故为4。

第二次询问:3、2的最近公共祖先,故为4。

第三次询问:3、5的最近公共祖先,故为1。

第四次询问:1、2的最近公共祖先,故为4。

第五次询问:4、5的最近公共祖先,故为4。

故输出依次为4、4、1、4、4。

思路:

这道题是最近公共祖先的模板题。。。

很显然,先dfs跑一遍,再由深度浅的往根跳,枚举该点是否合法

那么一个一个往上跳吧?

看一看范围:500000!!!!

TLE的飞起

怎么优化呢?
倍增一下

往上一个成不成立?

不成立

2个呢?

4个呢?
终究会成立

时复大大下降

见代码:

  1. #include<iostream>
  2. #include<cmath>
  3. #include<algorithm>
  4. #include<cstring>
  5. #include<cstdio>
  6. using namespace std;
  7. struct ljb{
  8. int from,to;
  9. }tu[];
  10. ],xyg[],n,m,root,sd[],f[][],have[],s,t;
  11. float bz;
  12. void read(int &x)
  13. {
  14. ;
  15. x=;
  16. char s=getchar();
  17. ')
  18. {
  19. if(s=='-')
  20. {
  21. f=-;
  22. }
  23. s=getchar();
  24. }
  25. ')
  26. {
  27. x=x*+s-';
  28. s=getchar();
  29. }
  30. x*=f;
  31. }
  32. void shd(int u,int h)
  33. {
  34. int ltt;
  35. sd[u]=h;
  36. ;i<=bz;i++)
  37. {
  38. <<i))
  39. {
  40. break;
  41. }
  42. f[u][i]=f[f[u][i-]][i-];
  43. }
  44. int k=head[u];
  45. )
  46. {
  47. ltt=tu[k].to;
  48. if(!have[ltt])
  49. {
  50. have[ltt]=;
  51. f[ltt][]=u;
  52. shd(ltt,h+);
  53. }
  54. k=xyg[k];
  55. }
  56. }
  57. int lca(int ltt,int kkk)
  58. {
  59. int lzn=sd[ltt];
  60. int chen_ze=sd[kkk];
  61. if(lzn!=chen_ze)
  62. {
  63. if(lzn<chen_ze)
  64. {
  65. swap(ltt,kkk);
  66. swap(lzn,chen_ze);
  67. }
  68. int cha=lzn-chen_ze;
  69. ;i<=bz;i++)
  70. {
  71. <<i)&cha)
  72. {
  73. ltt=f[ltt][i];
  74. }
  75. }
  76. }
  77. if(ltt==kkk)
  78. {
  79. return kkk;
  80. }
  81. ;
  82. ;i--)
  83. {
  84. )
  85. {
  86. continue;
  87. }
  88. if(f[ltt][i]==f[kkk][i])
  89. {
  90. continue;
  91. }
  92. else
  93. {
  94. ltt=f[ltt][i];
  95. kkk=f[kkk][i];
  96. }
  97. }
  98. ];
  99. }
  100. int main()
  101. {
  102. read(n);
  103. read(m);
  104. read(root);
  105. memset(head,-,sizeof(head));
  106. memset(xyg,-,sizeof(xyg));
  107. *(n-);
  108. ;i<=dsd;i+=)
  109. {
  110. read(s);
  111. read(t);
  112. tu[i].from=s;
  113. tu[i].to=t;
  114. tu[i+].from=t;
  115. tu[i+].to=s;
  116. xyg[i]=head[s];
  117. head[s]=i;
  118. xyg[i+]=head[t];
  119. head[t]=i+;
  120. }
  121. bz=log(n)/log()+;
  122. memset(have,,sizeof(have));
  123. memset(sd,,sizeof(sd));
  124. memset(f,-,sizeof(f));
  125. have[root]=;
  126. shd(root,);
  127. ;i<=n;i++)
  128. {
  129. ;j<=bz;j++)
  130. {
  131. <<j))
  132. {
  133. break;
  134. }
  135. }
  136. }
  137. ;i<=m;i++)
  138. {
  139. read(s);
  140. read(t);
  141. int y=lca(s,t);
  142. printf("%d\n",y);
  143. }
  144. ;
  145. }

【模板】最近公共祖先(LCA)的更多相关文章

  1. [模板] 最近公共祖先/lca

    简介 最近公共祖先 \(lca(a,b)\) 指的是a到根的路径和b到n的路径的深度最大的公共点. 定理. 以 \(r\) 为根的树上的路径 \((a,b) = (r,a) + (r,b) - 2 * ...

  2. Luogu 2245 星际导航(最小生成树,最近公共祖先LCA,并查集)

    Luogu 2245 星际导航(最小生成树,最近公共祖先LCA,并查集) Description sideman做好了回到Gliese 星球的硬件准备,但是sideman的导航系统还没有完全设计好.为 ...

  3. POJ 1470 Closest Common Ancestors(最近公共祖先 LCA)

    POJ 1470 Closest Common Ancestors(最近公共祖先 LCA) Description Write a program that takes as input a root ...

  4. POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA)

    POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA) Description A ...

  5. 【lhyaaa】最近公共祖先LCA——倍增!!!

    高级的算法——倍增!!! 根据LCA的定义,我们可以知道假如有两个节点x和y,则LCA(x,y)是 x 到根的路 径与 y 到根的路径的交汇点,同时也是 x 和 y 之间所有路径中深度最小的节 点,所 ...

  6. 最近公共祖先(LCA)模板

    以下转自:https://www.cnblogs.com/JVxie/p/4854719.html 首先是最近公共祖先的概念(什么是最近公共祖先?): 在一棵没有环的树上,每个节点肯定有其父亲节点和祖 ...

  7. HDU 2586 How far away ?(LCA模板 近期公共祖先啊)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 Problem Description There are n houses in the vi ...

  8. luogu3379 【模板】最近公共祖先(LCA) 倍增法

    题目大意:给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 整体步骤:1.使两个点深度相同:2.使两个点相同. 这两个步骤都可用倍增法进行优化.定义每个节点的Elder[i]为该节点的2^k( ...

  9. 最近公共祖先lca模板

    void dfs(int x,int root){//预处理fa和dep数组 fa[x][0]=root; dep[x]=dep[root]+1; for(int i=1;(1<<i)&l ...

  10. 【洛谷 p3379】模板-最近公共祖先(图论--倍增算法求LCA)

    题目:给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 解法:倍增. 1 #include<cstdio> 2 #include<cstdlib> 3 #include ...

随机推荐

  1. Xcode中不用Storyboard,用纯xib创建TabBar模式视图

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 如果要开发Tab类型视图的App,在Xcode中可以使用对应的 ...

  2. app如何更换用户头像信息呢?不妨这样做

    对于现在的手机应用而言,要想获得更多的人的使用,就需要给用户更多的自由功能才行,这也是基于用户体验开发软件的核心思想,一切以用户为中心,想用户之所想,做用户之所需.今天我就来谈一谈刚学到的一个关于设置 ...

  3. How to migrate data from another Mac using Mountain Lion and earlier

    链接:http://support.apple.com/zh-cn/HT4889

  4. 后端分布式系列:分布式存储-HDFS 架构解析

    本文以 Hadoop 提供的分布式文件系统(HDFS)为例来进一步展开解析分布式存储服务架构设计的要点. 架构目标 任何一种软件框架或服务都是为了解决特定问题而产生的.还记得我们在 <分布式存储 ...

  5. python中MySQLdb的使用

    先举一例: 一个 Python代码实例: # -*- coding: utf-8 -*-      #mysqldb     import time, MySQLdb         #连接     ...

  6. MySQL数据库内置函数

    mysql数据库中提供了很丰富的函数.mysql函数包括数学函数.字符串函数.日期和时间函数.条件判断函数.系统信息函数.加密函数.格式化函数等.通过这些函数,可以简化用户的操作. 简单介绍几类函数的 ...

  7. JavaScript 关键字

    JavaScript 关键字 和其他任何编程语言一样,JavaScript 保留了一些关键字为自己所用. JavaScript 同样保留了一些关键字,这些关键字在当前的语言版本中并没有使用,但在以后 ...

  8. (六十七)Xcode导入XMPPFramework框架

    首先下载XMPPFramework框架,将Vendor内容导入到工程中,其中KissXML需要额外的框架,需要通过Xcode设置. 选择工程选项中TARGETS的General标签,最下侧有Linke ...

  9. 《C语言点滴》书评

    说起C语言方面的书,你最先想到的是哪一本?不论图书本身是好是坏,反正我想到的是谭浩强的<C程序设计>--它已然是一部"圣经"了.那么,为什么赵岩老师还要写一本<C ...

  10. AngularJS进阶(三十九)基于项目实战解析ng启动加载过程

    基于项目实战解析ng启动加载过程 前言 在AngularJS项目开发过程中,自己将遇到的问题进行了整理.回过头来总结一下angular的启动过程. 下面以实际项目为例进行简要讲解. 1.载入ng库 2 ...