社区讨论

关于 LCA 倍增法的一些疑惑

P3379【模板】最近公共祖先(LCA)参与者 6已保存回复 6

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
6 条
当前快照
1 份
快照标识符
@mhjhpejn
此快照首次捕获于
2025/11/04 02:45
4 个月前
此快照最后确认于
2025/11/04 02:45
4 个月前
查看原帖
为什么倍增不会跳过LCA
如: 代码
CPP
#include<bits/stdc++.h>
//#define int long long
#define rew(i,a,b,c) for(int i=a;i<=b;i+=c)
//#include <Windows.h>
using namespace std;
const int nn=5e5+10;
int n,m,s,x,y;
int dep[nn];
vector<int> a[nn];
int fa[nn][30];
void youhua(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
}
void deep(int x,int p){
	fa[x][0]=p;
//	cout << x  << " " << p << endl;
//	Sleep(1000);
	for(int i=1;i<=20;i++)
		fa[x][i]=fa[fa[x][i-1]][i-1];
	dep[x]=dep[p]+1;
	for(int i:a[x])
		if(i!=p)
			deep(i, x);
}
int lca(int x,int y){
	if(dep[x]>dep[y]) swap(x,y);
	for(int i=20;i>=0;i--)
		if(dep[y]-(1<<i)>=dep[x]){
			y=fa[y][i];
		}
	if(x==y) return x;
	for(int i=20;i>=0;i--)
		if(fa[x][i]!=fa[y][i]){
			x=fa[x][i];
			y=fa[y][i];
		}
	return fa[x][0];
}
signed main(){
    youhua();
    cin>>n>>m>>s;
    rew(i,1,n-1,1){
    	cin>>x>>y;
    	a[x].push_back(y);
    	a[y].push_back(x); 
	}
    deep(s,s);
    for(int i=1;i<=m;i++){
    	cin>>x>>y;
    	cout<<lca(x,y)<<"\n";
	}
    return 0;
}
CPP
for(int i=20;i>=0;i--)
		if(fa[x][i]!=fa[y][i]){
			x=fa[x][i];
			y=fa[y][i];
		}
中 i=20 x,y同时向上跳2的20次方步
此时已经错过了LCA
(因为LCA只需要跳1步)
麻烦大佬回答一下~

回复

6 条回复,欢迎继续交流。

正在加载回复...