lca问题是最近公共祖先问题,一般是针对树结构的.现在有两种方法来解决这样的问题 1. On-line algorithm 用比较长的时间做预处理.然后对每次询问进行回答. 思路:对于一棵树中的两个节点,假设是u和v.我们要找到他们的最近的一个祖先,那么我们可以这样找,首先判断他们是不是一辈儿的人,也就是说他们的深度是不是一样的,如果一个较深(u),一个较浅(v).我们可以不断的找较深的节点的祖先,直到u和v的深度一致.如果此时u和v重合了,那么u(v)就是他们的最近公共最先,如果不重合,这时,…
基于深度的LCA算法:  对于两个结点u.v,它们的深度分别为depth(u).depth(v),对于其公共祖先w,深度为depth(w),u需要向上回溯depth(u)-depth(w)步,v需要depth(v)-depth(w)步. 因此,只需要u,v中深度较大的向上移,直到 depth(u)=depth(v) && 此时指向一个结点. 因此,求出LCA的时间复杂度为O(depth(u)+depth(v)):   求深度,只需要进行一次遍历,O(n). 如果是完全二叉树的话,相当于深度…
[简介] LCA(T,u,v):在有根树T中,询问一个距离根最远的结点x,使得x同时为结点u.v的祖先. RMQ(A,i,j):对于线性序列A中,询问区间[i,j]上的最值.见我的博客---RMQ ---- ST(Sparse Table)算法. [LCA算法] 解决LCA问题有多种算法,一种是离线的 Tarjan算法 ,还有在线的倍增法 ,还有就是转换为RMQ问题的在线算法. [LCA转化为RMQ] (一)对有根树T进行DFS,将遍历到的结点按照顺序记下,我们将得到一个长度为2N – 1的序列…
给定一棵树求任意两个节点的公共祖先 tarjan离线求LCA思想是,先把所有的查询保存起来,然后dfs一遍树的时候在判断.如果当前节点是要求的两个节点当中的一个,那么再判断另外一个是否已经访问过,如果访问过的话,那么它的最近公共祖先就是当前节点祖先. 下面是tarjan离线模板: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; ; struct Edge { i…
POJ.1330 Nearest Common Ancestors (LCA 倍增) 题意分析 给出一棵树,树上有n个点(n-1)条边,n-1个父子的边的关系a-b.接下来给出xy,求出xy的lca节点编号. LCA裸题,用倍增思想. 代码总览 #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #define nmax 80520 #define demen…
摘要: 本文主要介绍了解决LCA(最近公共祖先问题)的两种算法,分别是离线Tarjan算法和在线算法,着重展示了在具体题目中的应用细节. 最近公共祖先是指对于一棵有根树T的两个结点u和v,它们的LCA(T,u,v)表示一个结点x,满足x是u和v的公共祖先且x深度尽可能的大(也即最近). 求最近公共祖先有两种方法:一种是离线求解算法,也就是将询问全部存起来,处理完之后一次回答所有询问:另一种方法就是在线求解算法,对于每次询问,动态地回答. 离线算法Tarjan Tarjan算法就是利用深度优先搜索…
题目链接:http://poj.org/problem?id=1330 A rooted tree is a well-known data structure in computer science and engineering. An example is shown below: In the figure, each node is labeled with an integer from {1, 2,...,16}. Node 8 is the root of the tree. N…
pku 1330 Nearest Common Ancestors 题目链接: http://poj.org/problem?id=1330 题目大意: 给定一棵树的边关系,注意是有向边,因为这个WA一发.然后N个顶点给出了N-1有向边,求一对点之间的最近公共祖先 思路: 裸的离线tarjan Lca即可,但注意是有向边,需要先找出根节点,数组标记.其次要注意前向星存的时候只存一条边即可 代码: #include <iostream> #include <string.h> usi…
Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 19728   Accepted: 10460 Description A rooted tree is a well-known data structure in computer science and engineering. An example is shown below:    In the figure, e…
Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST. According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has…
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q…
题目链接:http://poj.org/problem?id=1330 题意就是求一组最近公共祖先,昨晚学了离线tarjan,今天来实现一下. 个人感觉tarjan算法是利用了dfs序和节点深度的关系,大致的意思:dfs如果不递归到递归基,那么dfs就会越递归越深,这个时候深度也是相应增加的,所以这个时候任意在已经遍历过的节点中选取两个点,计算他们的lca也就相当于是用并查集求他们的root.而dfs执行到递归基,转而执行下一个分支的时候,这个时候dfs的节点应当是小于等于之前执行到递归基的节点…
Nearest Common Ancestors Description A rooted tree is a well-known data structure in computer science and engineering. An example is shown below:  In the figure, each node is labeled with an integer from {1, 2,...,16}. Node 8 is the root of the tree.…
题意:求最近公共祖先. 解题关键:三种方法,1.st表 2.倍增法 3.tarjan 此次使用倍增模板(最好采用第一种,第二种纯粹是习惯) #include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<iostream> #include<cmath> using namespace std; typedef long long ll…
Description A rooted tree is a well-known data structure in computer science and engineering. An example is shown below:  In the figure, each node is labeled with an integer from {1, 2,...,16}. Node 8 is the root of the tree. Node x is an ancestor of…
[抄题]: Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allow a node to b…
其实这是一个裸求LCA的题目,我使用的是离线的Tarjan算法,但是这个题的AC对于我来说却很坎坷……首先是RE,我立马想到数组开小了,然后扩大了数组,MLE了……接着把数组调整适当大小,又交了一发,嗯?居然WA了,一定是我姿势不对,我换个编译器交一下,结果还是WA……这就比较尴尬了,最后审题目,发现了,我以为第一个输入的点就是根节点,其实不是,我们还需要找到入度为0的点来处理,这里做一个标记就可以了.还有就是题目的输入稍微有点坑,尤其是第二次输入,题目中说忽略所有空白,这就需要比较好的处理方法…
题目链接:http://poj.org/problem?id=1470 Write a program that takes as input a rooted tree and a list of pairs of vertices. For each pair (u,v) the program determines the closest common ancestor of u and v in the tree. The closest common ancestor of two n…
/* *********************************************** Author :kuangbin Created Time :2013-9-5 9:45:17 File Name :F:\2013ACM练习\专题学习\LCA\POJ1330_3.cpp ************************************************ */ #include <stdio.h> #include <string.h> #inclu…
午时刷题,难甚,遂小憩于桌上,惊醒,于梦中有所得,虽大声曰:吾已得tarjan之奥秘! 关于tarjan算法,其实就是一个递归加并查集的应用. 大致代码: #include<bits/stdc++.h> using namespace std; int find(int x){ .... } void join(int x,int y) { .... } void dfs(int x) { int len=v[x].size(); ; i<len; i++) //遍历x的子节点 { df…
题意比较费劲:输入看起来很麻烦.处理括号冒号的时候是用%1s就可以.还有就是注意它有根节点...Q次查询 在线st算法 /************************************************************************* > File Name: 3.cpp > Author: Howe_Young > Mail: 1013410795@qq.com > Created Time: 2015年10月08日 星期四 19时03分30秒…
题目请戳这里 题目大意:意如其名. 题目分析:本题只有一个查询,所以可以各种乱搞过去. 不过对于菜鸟而言,还是老老实实练习一下LCA算法. LCA有很多经典的算法.按工作方式分在线和离线2种. tarjan算法是经典的离线算法.这篇博客讲的太好懂了,我也不好意思班门弄斧,具体戳进去看看就会明白.重点是那个插图,一看秒懂. 在线算法主要有倍增算法和转RMQ算法. 另外LCA还有2种更为高效的O(n)-O(1)算法.一种请戳这里,另一种其实就是先将LCA转化成RMQ,再利用笛卡尔树O(n)预处理,O…
本题也是找LCA的题目,只是要求多次查询.一般的暴力查询就必定超时了,故此必须使用更高级的方法,这里使用Tarjan算法. 本题处理Tarjan算法,似乎输入处理也挺麻烦的. 注意: 由于查询的数据会极大,故此使用一个数组记录全部查询数据就会超时的. 我就载在这里了.查了好久才想到这点. 由于我使用了一个vector容器记录了查询数据.故此每次都循环这组这么大的数据,就超时了. ----解决的方法:使用一个vector<int> quest来记录查询数组.这样每次都仅仅须要循环某节点的邻接查询…
      树上倍增求LCA LCA指的是最近公共祖先(Least Common Ancestors),如下图所示: 4和5的LCA就是2 那怎么求呢?最粗暴的方法就是先dfs一次,处理出每个点的深度 然后把深度更深的那一个点(4)一个点地一个点地往上跳,直到到某个点(3)和另外那个点(5)的深度一样 然后两个点一起一个点地一个点地往上跳,直到到某个点(就是最近公共祖先)两个点"变"成了一个点 不过有没有发现一个点地一个点地跳很浪费时间? 如果一下子跳到目标点内存又可能不支持,相对来说…
前言: 给定一个有根树,若节点\(z\)是两节点\(x,y\)所有公共祖先深度最大的那一个,则称\(z\)是\(x,y\)的最近公共祖先(\(Least Common Ancestors\)),简称\(LCA\).它在许多与树相关问题中发挥较大作用 怎么求 以这题为例:luogu P3379 [模板]最近公共祖先(LCA) 朴素暴力 让深度更大的节点\(x\)向上走至与另一节点\(y\)在同一深度上,然后同时向上走直至相遇. 时间复杂度 \(O(N)\) 代码略 倍增优化 按照上面的思路,但是不…
目录 一.定义 二.LCA的实现流程 1. 预处理 2. 计算LCA 三.例题 例1:P3379 [模板]最近公共祖先(LCA) 四.树上差分 1. 边差分 2. 点差分 3. 例题 一.定义 给定一颗有根树,若节点z既是节点x的祖先,也是节点y的祖先,则称z是x,y的公共祖先.在x,y的祖先中,深度最大的一个节点称为x,y的最近公共祖先(Least Common Ancestors),记做LCA. 如图:LCA(5,7)=2:LCA(3,8)=1:LCA(6,10)=6. 二.LCA的实现流程…
LCA 在有根树中,两个节点 u 和 v 的公共祖先中距离最近的那个被称为最近公共祖先(LCA,Lowest Common Ancestor). 有多种算法解决 LCA 或相关的问题. 基于二分搜索的算法 首先搜索树中各个节点的深度: const int MAXN = 4e4 + 5; // 最大节点数 const int LOG_N = 60; // 树的最大深度 vector<int> G[MAXN]; // 树 int depth[MAXN]; // 节点深度 int parent[LO…
声明 咳咳,进入重难点的图论算法之一(敲黑板): 题目: 洛谷 P3379 先放标程,施工ing,以后补坑!!!(实在太难,一个模板这么长 [ 不过好像还是没有 AC自动机 长哎 ],注释都打半天,思维过程和算法讲解又打一堆,能用到此模板的都至少 省选+  了,但这个又不能因为懒而不打,毕竟要复习)     var rmq:..,..] of longint; first,next,en,one,b:..] of longint; deep,a:..] of longint; i,j,k,m,n…
本文是网络资料整理或部分转载或部分原创,参考文章如下: https://www.cnblogs.com/JVxie/p/4854719.html http://blog.csdn.net/ywcpig/article/details/52336496 https://baike.baidu.com/item/最近公共祖先/8918834?fr=aladdin 最近公共祖先,简称LCA(Lowest Common Ancestor): 所谓LCA:是当给定一个有根树T时,对于任意两个结点u.v,找…
什么是最近公共祖先? 在一棵没有环的树上,每个节点肯定有其父亲节点和祖先节点,而最近公共祖先,就是两个节点在这棵树上深度最大的公共的祖先节点. 换句话说,就是两个点在这棵树上距离最近的公共祖先节点. 所以LCA主要是用来处理当两个点仅有唯一一条确定的最短路径时的路径. 常用来求LCA的算法有:Tarjan/DFS(离线),ST/倍增(在线). 1,Tarjan tarjan的算法复杂度为$O(n+q)$. 思路:每进入一个节点u的深搜,就把整个树的一部分看作以节点u为根节点的小树,再搜索其他的节…