LCA 树链剖分

匿名 (未验证) 提交于 2019-12-03 00:40:02
//LCA //树链剖分 在线  #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> using namespace std; int n,m,root,cnt,head[500001]; int hvyson[500001],fa[500001],siz[500001],dep[500001],top[500001]; struct uio{     int to,next; }edge[1000001]; void add(int x,int y) {     edge[++cnt].next=head[x];     edge[cnt].to=y;     head[x]=cnt; } void dfs1(int x,int f,int depth) {     dep[x]=depth;     fa[x]=f;     siz[x]=1;     int maxson=-1;     for(int i=head[x];i;i=edge[i].next)     {         int y=edge[i].to;         if(y==f)             continue;         dfs1(y,x,depth+1);         siz[x]+=siz[y];         if(siz[y]>maxson)         {             hvyson[x]=y;             maxson=siz[y];         }     } } void dfs2(int x,int topf) {     top[x]=topf;     if(!hvyson[x])         return;     dfs2(hvyson[x],topf);     for(int i=head[x];i;i=edge[i].next)     {         int y=edge[i].to;         if(y==fa[x]||y==hvyson[x])             continue;         dfs2(y,y);     } } int lca(int x,int y) {     while(top[x]!=top[y])     {         if(dep[top[x]]<dep[top[y]])             swap(x,y);         x=fa[top[x]];     }     return dep[x]<dep[y]? x : y; } void do_something() {     for(int i=1;i<=m;i++)     {         int u,v;         scanf("%d%d",&u,&v);         printf("%d\n",lca(u,v));     } } int main() {     scanf("%d%d%d",&n,&m,&root);     for(int i=1;i<n;i++)     {         int u,v;         scanf("%d%d",&u,&v);         add(u,v);         add(v,u);     }     dfs1(root,0,1);     dfs2(root,root);     do_something();      return 0; }

原文:https://www.cnblogs.com/water-radish/p/9280519.html

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!