版权声明:转载请保留原地址 https://blog.csdn.net/u012972031/article/details/82847763
早就想写LCA了,奈何没有dfs基础,先做了最小生成树
废话就说到这里,上代码。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=500000+2;
int n,m,s;
int k=0;
int head[maxn],d[maxn],p[maxn][21];
struct Node{
int v,next;
}e[maxn*2];
void add(int u,int v){
e[k].v=v;
e[k].next=head[u];
head[u]=k++;
}
void dfs(int u,int fa){//预处理
d[u]=d[fa]+1;
p[u][0]=fa;
for(int i=1;(1<<i)<=d[u];i++){
p[u][i]=p[p[u][i-1]][i-1];
}
for(int i=head[u];i!=-1;i=e[i].next){
int v=e[i].v;
if(v!=fa){
dfs(v,u);
}
}
}
int lca(int a,int b){
if(d[a]>d[b])swap(a,b);
for(int i=20;i>=0;i--)
if(d[a]<=d[b]-(1<<i))b=p[b][i];
if(a==b)return a;
for(int i=20;i>=0;i--)
if(p[a][i]==p[b][i])continue;
else a=p[a][i],b=p[b][i];
return p[a][0];
}
int main(){
memset(head,-1,sizeof(head));
int a,b;
scanf("%d%d%d",&n,&m,&s);
for(int i=0;i<n-1;i++){
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
dfs(s,0);
for(int i=1;i<=m;i++){
scanf("%d%d",&a,&b);
int ans=lca(a,b);
printf("%d\n",ans);
}
return 0;
}
为什么没有注释呢?因为我把代码背过了。
所以还是分享一下我背代码的经验吧。
- 背代码之前请找一个大佬讲一下这个算法,让你大概了解算法的运行过程(
其实就是半懂不懂)!! - 一句一句的背,不要贪快
- 一个代码块一个代码块的背,比如赋值一部分 循环一部分,最终一个方法一个方法的背
另外,十分感谢gzh大佬为我们讲解了LCA算法QAQ