LCA

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=50010;
inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){x=10*x+ch-'0';ch=getchar();}
    return x*f;
}
int first[maxn],to[2*maxn],next[2*maxn],val[2*maxn],cnt;
int st[maxn][50];
int vis[maxn];
int dis[maxn];
int depth[maxn],f[maxn];
void add(int a,int b,int c)
{
    to[++cnt]=b;
    next[cnt]=first[a];
    first[a]=cnt;
    val[cnt]=c;
}
void ins(int a,int b,int c){add(a,b,c);add(b,a,c);}
void dfs(int x)
{
    st[x][0]=f[x];
    for(int i=1;i<=31;i++)st[x][i]=st[st[x][i-1]][i-1];
    for(int i=first[x];i;i=next[i])
    {
        if(to[i]==f[x])continue;
        f[to[i]]=x;
        depth[to[i]]=depth[x]+1;
        dis[to[i]]=val[i]+dis[x];
        dfs(to[i]);
    }
}
pair<int,int> lca(int u,int v)
{
    int a=u,b=v;
    if(depth[u]<depth[v])swap(u,v),swap(a,b);
    for(int i=31;i>=0;i--)
        if(depth[v]<depth[st[u][i]])u=st[u][i];
    
    if(u==v)return make_pair(v,dis[a]-dis[v]);
    for(int i=31;i>=0;i--)
    {
        if(st[u][i]==st[v][i])break;
        u=st[u][i],v=st[v][i];
    }
    return make_pair(st[u][0],dis[a]+dis[b]-(dis[st[u][0]]<<1));
}
int main()
{
    int n,q;
    scanf("%d",&n);
    for(int i=1;i<n;i++)
    {
        int u=read(),v=read(),w=read();
        ins(u,v,w);
    }
    depth[1]=1;
    vis[1]=1;
    dfs(1);
    q=read();
    pair<int,int> ans;
    for(int i=1;i<=q;i++)
    {
        int u,v;
        u=read(),v=read();
        ans=lca(u,v);
        cout<<ans.first<<" "<<ans.second<<endl;
    }
}
倍增
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=50010;
inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){x=10*x+ch-'0';ch=getchar();}
    return x*f;
}
int first[maxn],to[2*maxn],next[2*maxn],val[2*maxn],cnt;
int qfirst[maxn],qto[2*maxn],qnext[2*maxn],qval[2*maxn],qcnt,qdis[2*maxn],idq[maxn];
int n,q; 
int vis[maxn];
int depth[maxn],fa[maxn];
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
void Unite(int x,int y){if(find(x)!=find(y))fa[find(x)]=find(y);}
void add(int a,int b)
{
    to[++cnt]=b;
    next[cnt]=first[a];
    first[a]=cnt;
}
void ins(int a,int b){add(a,b);add(b,a);}
void qadd(int a,int b)
{
    qto[++qcnt]=b;
    qnext[qcnt]=qfirst[a];
    qfirst[a]=qcnt;
}
void qins(int a,int b){qadd(a,b);qadd(b,a);}

void Tarjan_dfs(int x,int f)
{
    int lca;
    fa[x]=x;
    vis[x]=1;
    for(int i=first[x];i;i=next[i])
    {
        if(to[i]==f)continue;
        vis[to[i]]=1;
        depth[to[i]]=depth[x]+1;
        Tarjan_dfs(to[i],x);
        Unite(to[i],x);
    }
    for(int i=qfirst[x];i;i=qnext[i])
    {
        if(vis[qto[i]])
        {
            lca=find(qto[i]);
            qval[idq[i]]=lca;
            qdis[idq[i]]=depth[qto[i]]+depth[x]-(depth[lca]<<1);
        }
    }
}
int main()
{
    n=read(),q=read();
    int u,v;
    for(int i=1;i<n;i++)
    {
        u=read(),v=read();
        ins(u,v);
    }
    for(int i=1;i<=n;i++)fa[i]=i;
    for(int i=1;i<=q;i++)
    {
        u=read(),v=read();
        qadd(u,v);idq[qcnt]=i;
        qadd(v,u);idq[qcnt]=i;
    }
    depth[1]=1;
    Tarjan_dfs(1,1);
    for(int i=1;i<=q;i++)cout<<qval[i]<<endl;
}
Tarjan
原文地址:https://www.cnblogs.com/Kong-Ruo/p/7766675.html