[模板]洛谷T3379 最近公共祖先(LCA) 倍增+邻接表

一年前听说的这东西。。。现在终于会了。。。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cmath>
  5 #include<ctime>
  6 #include<cstdlib>
  7 
  8 #include<string>
  9 #include<stack>
 10 #include<queue>
 11 #include<vector>
 12 #include<algorithm>
 13 #include<map>
 14 #include<set>
 15 
 16 #define M 500005
 17 
 18 using namespace std;
 19 
 20 inline void read(int &x){
 21     x=0;
 22     char t=getchar();
 23     bool f=0;
 24     
 25     while(t<'0' || t>'9'){
 26         if(t=='-')f=1;
 27         t=getchar();
 28     }
 29     
 30     while(t>='0' && t<='9'){
 31         x=(x<<3)+(x<<1)+t-'0';
 32         t=getchar();
 33     }
 34     
 35     if(f)x=-x;
 36 }
 37 
 38 void dfs(int,int);
 39 inline int LCA(int,int);
 40 
 41 int u[1000010];
 42 int v[1000010];
 43 int first[500010];
 44 int next[1000010];
 45 
 46 bool used[500010];
 47 int high[500010];
 48 int fa[500010][20];
 49 
 50 int n,m,root;
 51 int i,j;
 52 int x,y;
 53 
 54 int main(){
 55     memset(first,0,sizeof(first));
 56     memset(next,0,sizeof(next));
 57     
 58     memset(used,0,sizeof(used));
 59     
 60     read(n);read(m);read(root);
 61     
 62     for(i=1;i<n;i++){
 63         read(x);read(y);
 64         
 65         u[i]=x;
 66         v[i]=y;
 67         next[i]=first[u[i]];
 68         first[u[i]]=i;
 69         
 70         u[i+M]=y;
 71         v[i+M]=x;
 72         next[i+M]=first[u[i+M]];
 73         first[u[i+M]]=i+M;
 74     }
 75     
 76     dfs(root,1);
 77     
 78     for(i=1;i<=m;i++){
 79         read(x);read(y);
 80         
 81         if(high[x]>high[y])swap(x,y);
 82         
 83         printf("%d
",LCA(x,y));
 84     }
 85     
 86     return 0;
 87 }
 88 
 89 void dfs(int s,int h){
 90     int i,t;
 91     
 92     high[s]=h;
 93     used[s]=1;
 94     
 95     for(i=1;(1<<i)<h;i++)
 96         fa[s][i]=fa[fa[s][i-1]][i-1];
 97     
 98     t=first[s];
 99     
100     while(t!=0){
101         if(!used[v[t]]){
102             fa[v[t]][0]=s;
103             dfs(v[t],h+1);
104         }
105         
106         t=next[t];
107     }
108 }
109 
110 inline int LCA(int a,int b){
111     int dt=high[b]-high[a];
112     
113     for(register int i=0;(1<<i)<=dt;i++)
114         if((1<<i)&dt)b=fa[b][i];
115     
116     if(a==b)return a;
117     else{
118         for(register int i=19;i>=0;i--)
119             if(fa[a][i]!=fa[b][i]){
120                 a=fa[a][i];
121                 b=fa[b][i];
122             }
123         
124         return fa[a][0];
125     }
126 }
原文地址:https://www.cnblogs.com/running-coder-wfh/p/7570905.html