倍增求LCA

模版题 https://www.luogu.org/problemnew/show/P3379

讲解 https://www.bilibili.com/video/av41067872/?p=4&t=159

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define _ 0
 4 const int maxn = 5e5+5;
 5 const int maxbit = 20;
 6 vector<int> G[maxn];
 7 int depth[maxn], lg[maxn], father[maxn][maxbit];
 8 void dfs(int nowp, int fa){
 9     depth[nowp] = depth[fa] + 1;
10     father[nowp][0] = fa;
11     for(int j=1; j<=lg[depth[nowp]]+1; j++)
12         father[nowp][j] = father[father[nowp][j-1]][j-1];
13     for(int i=0; i<G[nowp].size(); i++){
14         if(G[nowp][i] != fa)
15             dfs(G[nowp][i], nowp);
16     }
17 }
18 int LCA(int u, int v){
19     if(depth[u] < depth[v]) swap(u, v);
20     //int dc = depth[u]-depth[v];
21     // for(int j=0; j<maxbit; j++){
22     //     if((dc>>j) & 1) u = father[u][j];
23     // }
24     while(depth[u] != depth[v]){
25         u = father[u][lg[depth[u]-depth[v]]];
26     }
27     if(u==v) return u;
28     for(int j=lg[depth[u]]; j>=0; j--){
29         if(father[u][j] != father[v][j]){
30             u = father[u][j]; v=father[v][j];
31         }
32     }
33     return father[u][0];
34 }
35 int main(){
36     lg[0] = -1;
37     for(int i=1; i<maxn; i++) lg[i] = lg[i>>1] + 1;
38     int n, m, s;
39     scanf("%d%d%d", &n, &m, &s);
40     int x, y;
41     for(int i=1; i<n; i++){
42         scanf("%d%d", &x, &y);
43         G[x].push_back(y);
44         G[y].push_back(x);
45     }
46     dfs(s,0);
47     while(m--){
48         scanf("%d%d", &x, &y);
49         printf("%d\n", LCA(x,y));
50     }
51     return (0^_^0);
52 }

 

posted @ 2019-05-15 19:54  企鹅君  阅读(133)  评论(0编辑  收藏  举报