其他分享
首页 > 其他分享> > LCA模板

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