lca 倍增法
题目链接:https://www.luogu.org/problemnew/show/P3379
AC代码:
1 #include<iostream>
2 #include<stack>
3 #include<queue>
4 #include<map>
5 #include<stdio.h>
6 #include<cstring>
7 #include<string>
8 #include<iomanip>
9 #include<vector>
10 #include<cmath>
11 #include<algorithm>
12 using namespace std;
13 # define ll long long
14 const int maxn = 500000+1010;
15 # define inf 0x3f3f3f3f
16 struct node
17 {
18 int to;
19 int nex;
20 } edge[maxn*2];
21 int head[maxn*2],depth[maxn*2],father[maxn][22];
22 int n,m,k,num;
23 void addedge(int fr,int to)
24 {
25 edge[num].to=to;
26 edge[num].nex=head[fr];
27 head[fr]=num++;
28 }
29 void dfs(int u,int root)
30 {
31 depth[u]=depth[root]+1;
32 father[u][0]=root;
33 for(int i=1; (1<<i)<=depth[u]; i++)//能往上更新多少就更新多少
34 {
35 father[u][i]=father[father[u][i-1]][i-1];
36 }
37 for(int i=head[u]; i!=-1; i=edge[i].nex)
38 {
39 int v=edge[i].to;
40 if(v==root)continue;
41 dfs(v,u);
42 }
43 }
44 int lca(int t1,int t2)
45 {
46 if(depth[t1]>depth[t2])swap(t1,t2);
47 for(int i=20; i>=0; i--)//和下面的一样,要从小的开始凑,否则到后面会凑不出来
48 {
49 if(depth[t1]<=depth[t2]-(1<<i))//先调整到同一个高度
50 {
51 t2=father[t2][i];
52 }
53 }
54 if(t1==t2)return t1;
55 for(int i=20; i>=0; i--)
56 {
57 if(father[t1][i]!=father[t2][i])//一起往上找
58 {
59 t1=father[t1][i];
60 t2=father[t2][i];
61 }
62 }
63 return father[t1][0];
64 }
65 int main()
66 {
67 num=0;
68 memset(head,-1,sizeof(head));
69 int t1,t2;
70 scanf("%d%d%d",&n,&m,&k);
71 for(int i=1; i<=n-1; i++)
72 {
73 scanf("%d%d",&t1,&t2);
74 addedge(t1,t2);
75 addedge(t2,t1);
76 }
77 dfs(k,k);
78 // for(int i=1;i<=n;i++){
79 // cout<<i<<" "<<depth[i]<<endl;
80 // }
81 for(int i=1; i<=m; i++)
82 {
83 scanf("%d %d",&t1,&t2);
84 printf("%d\n",lca(t1,t2));
85 }
86 return 0;
87 }
88