C++ P3379 【模板】最近公共祖先(LCA)

版权声明:转载请保留原地址 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;
}

为什么没有注释呢?因为我把代码背过了。

所以还是分享一下我背代码的经验吧。

  1. 背代码之前请找一个大佬讲一下这个算法,让你大概了解算法的运行过程(其实就是半懂不懂 )!!
  2. 一句一句的背,不要贪快
  3. 一个代码块一个代码块的背,比如赋值一部分 循环一部分,最终一个方法一个方法的背

另外,十分感谢gzh大佬为我们讲解了LCA算法QAQ

猜你喜欢

转载自blog.csdn.net/u012972031/article/details/82847763