- P3379 【模板】最近公共祖先(LCA)
- 倍增LCA,我们先把两个点提到同一高度,再统一开始跳。但我们在跳的时候不能直接跳到它们的LCA,因为这可能会误判,比如 4 和 8,在跳的时候,我们可能会认为 1 是它们的LCA,但 1 只是它们的祖先,它们的LCA其实是 3 。所以我们要跳到它们LCA的下面一层,比如 4 和 8 ,我们就跳到 4 和 5,然后输出它们的父节点.
-
#include<bits/stdc++.h> using namespace std; #define maxn 555555 int n,m,s,x,y,a,b,k; int deep[maxn],dis[maxn],tot; int head[maxn],dp[maxn][22]; struct node { int v,to; } edge[maxn*2]; void add(int x,int y) { edge[++tot].v=y; edge[tot].to=head[x]; head[x]=tot; } void dfs(int cur,int pre) { deep[cur]=deep[pre]+1; dp[cur][0]=pre; for(int i=1; (1<<i)<=deep[cur]; i++) dp[cur][i]=dp[dp[cur][i-1]][i-1]; for(int i=head[cur]; i!=-1; i=edge[i].to) if(edge[i].v!=pre) dfs(edge[i].v,cur); } int lca(int x,int y) { if(deep[x]<deep[y]) swap(x,y); for(int i=k; i>=0; i--) if(deep[x]-(1<<i)>=deep[y]) x=dp[x][i]; if(x==y) return x; for(int i=k; i>=0; i--) if(dp[x][i]!=dp[y][i]) { x=dp[x][i]; y=dp[y][i]; } return dp[x][0]; } int main() { scanf("%d%d%d",&n,&m,&s); for(int i=1; i<=n; i++) head[i]=-1; for(int i=1; i<n; i++) { scanf("%d%d",&x,&y); add(x,y); add(y,x); } dfs(s,0); k=log(n)/log(2); for(int i=1; i<=m; i++) { scanf("%d%d",&x,&y); printf("%d\n",lca(x,y)); } return 0; }
P3379 -最近公共祖先(LCA)
最新推荐文章于 2024-07-27 17:52:51 发布