LCA模板
作者:互联网
倍增算法
类似二分思想
用fa[i][j]表示第i个数的第2^j个祖先
用dep[x]是第x的深度
每次对于两个节点 将深一点的点跳到和浅一点的同一个位置 然后再将两个点同时跳到同一个点
跳的时候跳以2的倍数跳
//预处理fa数组和de数组
//fa[i][j]第i个节点的第2^j个祖先 de[x] x的深度
void dfs(ll x, ll father){
fa[x][0] = father;
de[x] = de[father] + 1;
for(ll i = 1; (1 << i) <= de[x]; i++){
fa[x][i] = fa[fa[x][i - 1]][i - 1];
}
for(int i = 0 ; i < g[x].size(); i++){
ll y = g[x][i];
if(y != father){
dfs(g[x][i], x);
}
}
}
//寻找lca
ll LCA(ll u, ll v){
if(de[u] < de[v]) swap(u, v);
//因为最多不会超过2^20
//先将深一点的节点跳到和浅一点的节点同一个高度
for(int i = 20; i >= 0; i--){
if(de[fa[u][i]] >= de[v]) u = fa[u][i];
if(u == v) return u;
}
//将两个节点同时向上跳 如果跳到同一点 可能不一定是最小的祖先
//所以只有向上跳跳到的不是同一点才可以跳
//直到最后两个点都跳到其公共最小祖先的下一个点 fa[v][0]即要找的最小公共祖先
for(int i = 20; i >= 0; i--){
if(fa[u][i] != fa[v][i]){
u = fa[u][i];
v = fa[v][i];
}
}
return fa[v][0];
}
标签:祖先,ll,de,father,fa,LCA,节点,模板 来源: https://www.cnblogs.com/yaqu-qxyq/p/16392900.html