[模板]洛谷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\n",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 }