但LCA就不一样了,他可以实现并查集的操作,还可以查询两者的最近祖先,emm,关于这一点的应用嘛,就是比如说求树上最短路的问题,LCA会方便很多 3.LCA倍增算法本法 LCA的雏形就是单纯地考虑x,y同时向自己的爸爸跳,直到相遇,但如果是两条链连在树根上,x,y又分别是两个叶子结点的话。。。会很慢很慢 那么问题来...
第一步肯定是dfs求每个点的深度。 查询lca(a,b)时,先把ab中深度较大的点往上移,移到两个点深度相同为止; 现在两个点深度相同了,于是两个点一起往上移,直至移到同一个位置,即最近公共祖先。 倍增法其实就是在暴力的基础上,对把两个点上移的过程进行倍增操作(因为一步一步走真的很慢啊) 倍增操作即:如...
intLCA(intx,inty){if(deep[x]<deep[y])//不妨让x节点是在y下方的节点swap(x,y);//交换,维持性质while(deep[x]!=deep[y])//当我们还没有使得节点同样深度x=fa[x][lg2[deep[x]-deep[y]]];//往上面跳跃,deep[x]-deep[y]是高度差.if(x==y)//发现Lca(x,y)=yreturnx;//返回吧,找到了...
直到这个迭代结点和另一个结点深度相同, 那么这两个深度相同的结点的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]; 注意...
int lca(int x,int y){ if(depth[x]<depth[y]) swap(x,y); int i; for(i=15;i>=0;i--){ if(depth[fa[x][i]]>=depth[y]) x=fa[x][i]; } if(x==y) return x; for(i=15;i>=0;i--){ if(fa[x][i]!=fa[y][i]){ ...
考虑其他, 我们思考这么一个问题: 对于两个深度不同的结点, 把深度更深的那个向其父节点迭代, 直到这个迭代结点和另一个结点深度相同, 那么这两个深度相同的结点的Lca也就是原两个结点的Lca. 因此第二种情况转化成第一种情况来求解Lca是可行的. 这里我们使用倍增法以最快的速度找到相同的深度,然后开始求LCA。
dfs(s,0);intans =0;for(inti =1;i<=m;i++) {inta,b; read(a); read(b); ans = lca(a,b);cout<< ans <<endl; }return0; } 参考文章: 李白莘莘学子,树上倍增求LCA详解,https://www.cnblogs.com/lbssxz/p/11114819.html(讲的好啊讲的好)...