简介 最近公共祖先 \(lca(a,b)\) 指的是a到根的路径和b到n的路径的深度最大的公共点. 定理. 以 \(r\) 为根的树上的路径 \((a,b) = (r,a) + (r,b) - 2 * (r,fa(lca))\). (树上差分) 求法 tarjan 离线算法, 总时间 \(O(n+q)\). (q表示询问次数) //利用前向星存储询问 struct te{int t,pr,lca;}edge[1000050],qedge[1000050]; int head[500050],pe…
Luogu 2245 星际导航(最小生成树,最近公共祖先LCA,并查集) Description sideman做好了回到Gliese 星球的硬件准备,但是sideman的导航系统还没有完全设计好.为了方便起见,我们可以认为宇宙是一张有N 个顶点和M 条边的带权无向图,顶点表示各个星系,两个星系之间有边就表示两个星系之间可以直航,而边权则是航行的危险程度. sideman 现在想把危险程度降到最小,具体地来说,就是对于若干个询问(A, B),sideman 想知道从顶点A 航行到顶点B 所经过的…
POJ 1470 Closest Common Ancestors(最近公共祖先 LCA) Description 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 co…
POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA) 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…
高级的算法——倍增!!! 根据LCA的定义,我们可以知道假如有两个节点x和y,则LCA(x,y)是 x 到根的路 径与 y 到根的路径的交汇点,同时也是 x 和 y 之间所有路径中深度最小的节 点,所以,我们可以用遍历路径的方法求 LCA. 但想想都知道啦,这种遍历的方法肯定too slow,最坏情况时可达到O(n),数据大点儿,就光荣TLE了. 所以我们高级的化身——倍增算法就出现了! 谈谈倍增—— 倍增简单来讲就是两个点跳到同一高度后,再一起往上跳,直到跳到一个共同的点,就能找到它们的最近公…
题目大意:给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 整体步骤:1.使两个点深度相同:2.使两个点相同. 这两个步骤都可用倍增法进行优化.定义每个节点的Elder[i]为该节点的2^k(或者说是二进制中的1,10,100,1000...)辈祖先.求它时要利用性质:cur->Elder[i]==cur->Elder[i-1]->Elder[i-1].具体步骤看代码. #include <cstdio> #include <cstring> #inclu…
以下转自:https://www.cnblogs.com/JVxie/p/4854719.html 首先是最近公共祖先的概念(什么是最近公共祖先?): 在一棵没有环的树上,每个节点肯定有其父亲节点和祖先节点,而最近公共祖先,就是两个节点在这棵树上深度最大的公共的祖先节点. 换句话说,就是两个点在这棵树上距离最近的公共祖先节点. 所以LCA主要是用来处理当两个点仅有唯一一条确定的最短路径时的路径. 有人可能会问:那他本身或者其父亲节点是否可以作为祖先节点呢? 答案是肯定的,很简单,按照人的亲戚观念…
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 Problem Description There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this "How far is it if I want to go from house A to house…
void dfs(int x,int root){//预处理fa和dep数组 fa[x][0]=root; dep[x]=dep[root]+1; for(int i=1;(1<<i)<dep[x];i++) fa[x][i]=fa[fa[x][i-1]][i-1]; for(int i=0;i<ve[x].size();i++)dfs(ve[x][i],x); } int lca(int a,int b){//计算两个节点的最近公共祖先 if(dep[a]>dep[b])s…
题目:给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 解法:倍增. 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 using namespace std; 6 #define N 500010 7 #define D 20 8 9 int n,m,root,len=0; 10 int last[N],fa[N][D],dep[N];…