树链剖分求lca模板

传说中比O(1)还快的求LCA的方法
再加上正向表优化,

#include
#include
#include
using namespace std;
#define M 100005
#define FOR(i,x,y) for(int i=(x);i<=(y);i++)
#define DOR(i,x,y) for(int i=(x);i>=(y);i--)
int nxt[M<<1],head[M],To[M<<1],V[M<<1];
int tta;
void addedge(int a,int b,int c){
    nxt[++tta]=head[a];
    head[a]=tta;
    To[tta]=b;
    V[tta]=c;
}
int fa[M],dep[M],dis[M],sz[M],son[M],Top[M],Tid[M],tim;
void ldfs(int x,int f){
    fa[x]=f;
    dep[x]=dep[f]+1;
    sz[x]=1;
    for(int i=head[x];i;i=nxt[i]){
        int y=To[i];
        if(y==f)continue;
        dis[y]=dis[x]+V[i];
        ldfs(y,x);
        sz[x]+=sz[y];
        if(!~son[x]||sz[son[x]]>sz[son[x]])son[x]=y;
    }
}
void rdfs(int x,int tp){
    Top[x]=tp;
    Tid[x]=++tim;
    if(!~son[x])return;
    rdfs(son[x],tp);
    for(int i=head[x];i;i=nxt[i]){
        int y=To[i];
        if(y==fa[x]||y==son[x])continue;
        rdfs(y,y);
    }
}
int LCA(int x,int y){
    while(Top[x]!=Top[y]){
        if(dep[Top[x]]if(dep[x]>dep[y])swap(x,y);
    return x;
}
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    memset(son,-1,sizeof(son));
    FOR(i,1,n-1){
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        addedge(a,b,c);
        addedge(b,a,c);
    }
    ldfs(1,0);
    rdfs(1,1);
    for(int i=1;i<=m;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        int lca=LCA(x,y);
        printf("%d\n",dis[x]+dis[y]-2*dis[lca]);
    }
    return 0;
}

你可能感兴趣的:(树链剖分求lca模板)