LCA模板(数剖实现)
Posted frankchen831x
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LCA模板(数剖实现)相关的知识,希望对你有一定的参考价值。
题目链接:https://www.luogu.org/problemnew/show/P3379
题意:LCA模板题。
思路:今天开始学树剖,先拿lca练练。树剖解lca,两次dfs复杂度均为O(n),每次查询为logn,因此总复杂度为:O(2*n+m*logn)。
代码:
#include<cstdio> #include<cstring> using namespace std; const int maxn=500005; struct node int v,next; edge[2*maxn]; int n,m,s,cnt,size[maxn],head[maxn],depth[maxn],son[maxn],fa[maxn],top[maxn]; void add(int u,int v) edge[++cnt].v=v; edge[cnt].next=head[u]; head[u]=cnt; void dfs1(int x) size[x]=1; depth[x]=depth[fa[x]]+1; for(int i=head[x];i;i=edge[i].next) int v=edge[i].v; if(v==fa[x]) continue; fa[v]=x; dfs1(v); size[x]+=size[v]; if(!son[x]||size[son[x]]<size[v]) son[x]=v; void dfs2(int x,int f) top[x]=f; if(son[x]) dfs2(son[x],f); for(int i=head[x];i;i=edge[i].next) int v=edge[i].v; if(v==fa[x]||v==son[x]) continue; dfs2(v,v); void lca() for(int i=0;i<m;++i) int x,y; scanf("%d%d",&x,&y); while(top[x]!=top[y]) if(depth[top[x]]>depth[top[y]]) x=fa[top[x]]; else y=fa[top[y]]; printf("%d\n",depth[x]<depth[y]?x:y); int main() scanf("%d%d%d",&n,&m,&s); for(int i=1;i<n;++i) int u,v; scanf("%d%d",&u,&v); add(u,v); add(v,u); dfs1(s); dfs2(s,s); lca(); return 0;
以上是关于LCA模板(数剖实现)的主要内容,如果未能解决你的问题,请参考以下文章