LCA树链法

来源:互联网 发布:日本dna数据库 编辑:程序博客网 时间:2024/06/05 03:04
#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define maxn 500005using namespace std;int n,m;int info[maxn],Prev[maxn*2],to[maxn*2],cnt_e;int dep[maxn],Fa[maxn],bel[maxn],len[maxn],idx[maxn],head[maxn],siz[maxn],cnt_l;bool vis[maxn];int Q[maxn],L,R;void insert(int u,int v){    cnt_e++;    Prev[cnt_e]=info[u],to[cnt_e]=v,info[u]=cnt_e;}void split(int s){    L=0;cnt_l=0;    memset(dep,0,sizeof dep);    dep[Q[R=1]=s]=1;    Fa[s]=-1;        while(L<R){        int now=Q[++L];        vis[now]=0;        for(int i=info[now];i;i=Prev[i])            if(!dep[to[i]])                dep[Q[++R]=to[i]]=dep[Fa[to[i]]=now]+1;    }        for(int i=R;i;i--)    {        int now=Q[i],son=-1;        siz[now]=1;        for(int j=info[now];j;j=Prev[j])            if(vis[to[j]]){                siz[now]+=siz[to[j]];                if(son==-1 || siz[to[j]]>siz[son]) son=to[j];             }                    if(son==-1){            idx[now]=len[++cnt_l]=1;            bel[head[cnt_l]=now]=cnt_l;        }        else{            idx[now]=++len[bel[now]=bel[son]];            head[bel[now]]=now;        }                vis[now]=1;    }}int LCA(int u,int v){    while(bel[u]!=bel[v]){        if(dep[head[bel[u]]]<dep[head[bel[v]]]) v=Fa[head[bel[v]]];        else u=Fa[head[bel[u]]];    }    if(dep[u]<dep[v]) return u;    return v;}int main(){    int s;    scanf("%d%d%d",&n,&m,&s);        int u,v;    for(int i=1;i<n;i++)    {        scanf("%d%d",&u,&v);        insert(u,v);        insert(v,u);    }        split(s);        for(int i=1;i<=m;i++){        scanf("%d%d",&u,&v);        printf("%d\n",LCA(u,v));    }}


原创粉丝点击