1. 程式人生 > >[模板] 樹鏈剖分找LCA

[模板] 樹鏈剖分找LCA

std ret gist father fin can truct tin 樹鏈剖分

#include <cstdio>
#include <cstring>
#define MAX 500005

int d[MAX],fa[MAX],size[MAX],top[MAX],son[MAX];
int N,M,S,tot=0;
int head[MAX];

struct edge{
    int v,next;
}G[MAX<<1];

inline void add(int u,int v){
    G[++tot].v=v;G[tot].next=head[u];head[u]=tot;
}

inline void dfs1(int u,int
father){ d[u]=d[father]+1; fa[u]=father; size[u]=1; int max = 0; for(register int i=head[u];i;i=G[i].next){ int v = G[i].v; if(v==father)continue; dfs1(v,u); size[u]+=size[v]; if(size[v]>max)son[u]=v,max=size[v]; } } inline void dfs2(int
u,int high,int father){ top[u]=high; if(son[u]==0)return; dfs2(son[u],high,u); for(register int i=head[u];i;i=G[i].next){ int v = G[i].v; if(v==son[u]||v==father)continue; dfs2(v,v,u); } } inline void swap(int* u,int* v){ int t = *u;*u = *v;*v = t; } inline
int LCA(int u,int v){ while(top[u]!=top[v]){ if(d[top[u]]<d[top[v]])swap(&u,&v); u = fa[top[u]]; } return d[u]>d[v]?v:u; } int main(){ std::memset(head,0,sizeof(head)); std::memset(son,0,sizeof(son)); scanf("%d%d%d",&N,&M,&S); int u,v; for(register int i=1;i<N;++i){ scanf("%d%d",&u,&v); add(u,v);add(v,u); } d[0]=0; dfs1(S,0); dfs2(S,0,0); for(register int i=1;i<=M;++i){ scanf("%d%d",&u,&v); printf("%d\n",LCA(u,v)); } return 0; }

[模板] 樹鏈剖分找LCA