第一步肯定是dfs求每个点的深度。 查询lca(a,b)时,先把ab中深度较大的点往上移,移到两个点深度相同为止; 现在两个点深度相同了,于是两个点一起往上移,直至移到同一个位置,即最近公共祖先。 倍增法其实就是在暴力的基础上,对把两个点上移的过程进行倍增操作(因为一步一步走真的很慢啊) 倍增操作即:如...
1intLca(intu,intv)2{3if(depth[u] < depth[v]) swap(u, v);//使满足u深度更大, 便于后面操作4inti = -1, j;5//i求的是最大二分跨度6while((1<< (i +1)) <= depth[u]) ++i;78//下面这个循环是为了让u和v到同一深度9for(j = i; j >=0; --j) {10if(depth[u] - (1<<...
直到这个迭代结点和另一个结点深度相同, 那么这两个深度相同的结点的Lca也就是原两个结点的Lca. 因此第二种情况转化成第一种情况来求解Lca是可行的. 这里我们使用倍增法以最快的速度找到相同的深度,然后开始求LCA。求
倍增法求LCA intdep[N];intfa[N][20];voiddfs(intu,intp){dep[u]=dep[p]+1;fa[u][0]=p;for(inti=1;i<=19;i++){fa[u][i]=fa[fa[u][i-1]][i-1];}for(inti=h[u];i;i=e[i].ne){intv=e[i].v;if(v!=p){dfs(v,u);}}}intlca(intu,intv){if(dep[u]<dep[v]){...
LCA的实现 首先,将两个元素移到同一层里 if(Dep[x]<Dep[y])swap(x,y); k=Dep[x]-Dep[y]; for(int i=0;i<=s;i++){ if(k&(1<=0;i--){ if(Fa[x][i]!=Fa[y][i]){ x=Fa[x][i]; y=Fa[y][i]; } } return Fa[x][0]; 注意...
AcWing1172 祖孙询问(倍增法求lca模板),注意点:要倒序,否则无法刚好二进制拼凑设置哨兵,0的深度为0,且超过树的根节点的值为=0#include<iostream>#include<queue>#include#include<vector>#include<cstdio>#include<algorithm>
考虑其他, 我们思考这么一个问题: 对于两个深度不同的结点, 把深度更深的那个向其父节点迭代, 直到这个迭代结点和另一个结点深度相同, 那么这两个深度相同的结点的Lca也就是原两个结点的Lca. 因此第二种情况转化成第一种情况来求解Lca是可行的. 这里我们使用倍增法以最快的速度找到相同的深度,然后开始求LCA。
倍增法求LCA LCA(Least Common Ancestors)的意思是最近公共祖先,即在一棵树中,找出两节点最近的公共祖先。 倍增法是通过一个数组来实现直接找到一个节点的某个祖先,这样我们就可以在O(logn)的时间内求出求出任意节点的任意祖先。 然后先把两个节点中转化为深度相同的节点,然后一起向上递增,知道找到相同的节点,该...
倍增法求LCA 倍增算法可以在线求树上两个点的LCA,时间复杂度为nlogn 预处理:通过dfs遍历,记录每个节点到根节点的距离dist[u],深度d[u] init()求出树上每个节点u的2^i祖先p[u][i] 求最近公共祖先,根据两个节点的的深度,如不同,向上调整深度大的节点,使得两个节点在同一层上,如果正好是祖先结束,否则,将...
思路:裸LCA。这里主要练习一下倍增法,感觉这种思路和代码实现很简单,而且能感觉实用性很大的,很值得学习 倍增法要理解对2的次方的枚举顺序 如果是要走固定步数,那么顺序枚举与i位与为1就行 如果是要求一个临界位置,那么要从大到小枚举 #include #include...