首页 > 其他 > 详细

LCA(树剖)

时间:2019-11-07 23:03:09      阅读:108      评论:0      收藏:0      [点我收藏+]

树剖求LCA.

处理链之后直接跑.不多说.

#pragma GCC target("f16c")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse3","sse2","sse")
#pragma GCC optimize(3,"Ofast","inline")
#pragma GCC optimize("no-stack-protector")
#pragma GCC target("avx","sse4","sse4.1","sse4.2","ssse3")
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e6+50;
const int INF=0x3f;
const double eps=1e-5;
int n,m;
int tot;
int tim;
int s,t;
int f[N];
int ai[N];
int head[N];
int deep[N],size[N],bis[N],top[N],dfsx[N];
struct Edge {
    int u,v;
} edge[N*3];
inline void add(int x,int y) {
    edge[++tot].u=head[x];
    edge[tot].v=y;
    head[x]=tot;
    return ;
}
inline void dfs1(int now,int fa) {
    deep[now]=deep[fa]+1;
    size[now]=1;
    f[now]=fa;
    for(int i=head[now];i;i=edge[i].u){
        int to=edge[i].v;
        if(to==fa) continue;
        dfs1(to,now);
        size[now]+=size[to];
        if(size[to]>size[bis[now]]) bis[now]=to;
    }
    return ;
}
inline void dfs2(int now,int Top,int fa) {
    top[now]=Top;
    dfsx[now]=++tim;
    if(bis[now]) dfs2(bis[now],Top,now);
    for(int i=head[now];i;i=edge[i].u){
        int to=edge[i].v;
        if(to==fa||to==bis[now]) continue ;
        dfs2(to,to,now);
    }
    return ;
}
inline int LCA(int x,int y){
    while(top[x]!=top[y]){
        if(deep[top[x]]<deep[top[y]]) swap(x,y);
        x=f[top[x]];
    }
    if(deep[x]<deep[y]) swap(x,y);
    return y;
}
int main() {
    int root;
    scanf("%d%d%d",&n,&m,&root);
    for(int i=1;i<n;++i){
        scanf("%d%d",&s,&t);
        add(s,t);
        add(t,s);
    }
    dfs1(root,0);
    dfs2(root,root,0);
    for(int i=1;i<=m;++i){
        scanf("%d%d",&s,&t);
        printf("%d\n",LCA(s,t));
    }
    return 0;
}

 

LCA(树剖)

原文:https://www.cnblogs.com/Fast-Bird/p/11816142.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!