P3379 【模板】最近公共祖先(LCA)

来源:互联网 发布:sqlserver未安装 编辑:程序博客网 时间:2024/05/16 02:03
先跑出欧拉序列,并求出每个点在欧拉序列中最先出现的位置pos。
然后两点的lca就是对应的pos之间的最小值。rmq就好了。
#include<cstdio>#include<cstring>#include<iostream>#include<vector>#include<algorithm>#include<set>#include<map>using namespace std;#define rep(i,j,k) for(i=j;i<=k;++i)#define per(i,j,k) for(i=j;i>=k;--i)#define G getchar()#define LL long long#define pll pair<int,int>#define mkp make_pair#define X first#define Y secondconst int N=500005;int n,m,rt;int tot,he[N],ne[N<<1],to[N<<1];int phi[N<<1],pos[N],ln,dep[N];int Min[N<<1][21],cs,bit[N<<1];void read(int &x){char ch=G;while(ch<48||ch>57)ch=G;for(x=0;ch>47&&ch<58;ch=G)x=x*10+ch-48;}void add(int x,int y){to[++tot]=y;ne[tot]=he[x];he[x]=tot;}void DFS(int x){int i,y;phi[pos[x]=++ln]=x;for(i=he[x];i;i=ne[i])if(!pos[y=to[i]]){dep[y]=dep[x]+1;DFS(y);phi[++ln]=x;}}int get(int i,int j){if(i>j)swap(i,j);int t=bit[j-i+1];int u=Min[i][t],v=Min[j-(1<<t)+1][t];return dep[u]<dep[v]?u:v;}int main(){int i,x,y,t;for(x=2,t=1;x<1000000;x<<=1)bit[x]=t++;rep(x,3,1000000)if(!bit[x])bit[x]=bit[x-1];read(n);read(m);read(rt);tot=1;rep(i,2,n){read(x);read(y);add(x,y);add(y,x);}dep[rt]=1;DFS(rt);per(i,ln,1){Min[i][0]=phi[i];for(t=1;ln-i+1>=(1<<t);cs=max(cs,t++)){x=i+(1<<t-1);Min[i][t]=dep[Min[i][t-1]]<dep[Min[x][t-1]]?Min[i][t-1]:Min[x][t-1];}}while(m--){read(x);read(y);printf("%d\n",get(pos[x],pos[y]));}return 0;}

原创粉丝点击