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
",lca(t1,t2));
85     }
86     return 0;
87 }
88  
原文地址:https://www.cnblogs.com/letlifestop/p/10262798.html