倍增求LCA

匿名 (未验证) 提交于 2019-12-02 23:49:02
 1 #include<iostream>  2 #include<cstdio>  3 #include<cstring>  4 #include<algorithm>  5 #include<cstdlib>  6 using namespace std;  7 #define maxn 500010  8   9 int n,m,s,tot; 10 int deep[maxn],first[maxn],fa[maxn][22]; 11 struct edge{ 12     int nextx,to; 13 }e[maxn<<1]; 14  15 void add(int u,int v) 16 { 17     tot++; 18     e[tot].to=v; 19     e[tot].nextx=first[u]; 20     first[u]=tot; 21 } 22  23 void dfs(int x,int f,int depth) 24 { 25     deep[x]=depth; 26     fa[x][0]=f; 27     for(int i=1;(1<<i)<=deep[x];i++)//注意此处应从1开始,i-1必须为正 28         fa[x][i]=fa[fa[x][i-1]][i-1]; 29     for(int i=first[x];i;i=e[i].nextx) 30     { 31         int u=e[i].to; 32         if(u==f)continue; 33         fa[u][0]=x; 34         dfs(u,x,depth+1); 35     } 36 } 37  38 int get_lca(int x,int y) 39 { 40     if(deep[x]<deep[y])swap(x,y); 41     for(int i=20;i>=0;i--)//注意此处应从0开始循环,保证可以跳一步 42         if(deep[fa[x][i]]>=deep[y])x=fa[x][i]; 43     if(x==y)return x; 44     for(int i=20;i>=0;i--)//从0开始,理由同上 45         if(fa[x][i]!=fa[y][i]) 46             x=fa[x][i],y=fa[y][i]; 47     return fa[x][0]; 48 } 49  50 int main() 51 { 52     scanf("%d%d%d",&n,&m,&s); 53     for(int i=1;i<=n-1;i++) 54     { 55         int a,b; 56         scanf("%d%d",&a,&b); 57         add(a,b),add(b,a); 58     } 59     dfs(s,s,1); 60     for(int i=1;i<=m;i++) 61     { 62         int a,b; 63         scanf("%d%d",&a,&b); 64         cout<<get_lca(a,b)<<"\n"; 65     } 66     return 0; 67 }

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