P3379 【模板】最近公共祖先(LCA)
2017-07-14 10:03
471 查看
先跑出欧拉序列,并求出每个点在欧拉序列中最先出现的位置pos。
然后两点的lca就是对应的pos之间的最小值。rmq就好了。
然后两点的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 second const int N=500005; int n,m,rt; int tot,he ,ne[N<<1],to[N<<1]; int phi[N<<1],pos ,ln,dep ; 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; }
相关文章推荐
- 洛谷——P3379 【模板】最近公共祖先(LCA)
- 洛谷 P3379 【模板】最近公共祖先(LCA)
- P3379 【模板】最近公共祖先(LCA)
- P3379 【模板】最近公共祖先(LCA)
- 洛谷 P3379 【模板】最近公共祖先(LCA)
- 洛谷 P3379 【模板】最近公共祖先(LCA)
- 洛谷3379 【模板】最近公共祖先(LCA)
- LCA(最近公共祖先)模板
- 【模板】最近公共祖先(LCA)
- [Luogu P3379]【模板】最近公共祖先(LCA)
- hiho一下 第十五周 最近公共祖先·二 - 更新一下tarjan离线LCA模板
- 【模板】最近公共祖先(LCA)
- 倍增法求最近公共祖先(LCA)的算法模板
- 图论--最近公共祖先问题(LCA)模板
- 洛谷 P 3379 【模板】最近公共祖先(LCA)
- 洛谷P3379 【模板】最近公共祖先(LCA)
- LCA 最近公共祖先 (笔记、模板)
- 洛谷 P 3379 【模板】最近公共祖先(LCA)
- 算法模板之最近公共祖先问题(LCA)
- 树剖——【模板】最近公共祖先(LCA)