不会 准备研究一波!!!
#include<bits/stdc++.h>
const int maxn = ;
using namespace std;
vector<int> g[maxn];
int par[][maxn], dep[maxn], n, m, ml;
void dfs(int v, int p, int d)
{
par[][v] = p;
dep[v] = d;
for (int i = ; i < g[v].size(); ++i){
if (g[v][i] != p) dfs(g[v][i], v, d + );
}
return ;
}
void init(int v)
{
dfs(v, -, );
int sum = ;
while (sum <= n) sum <<= , ++ml;
for (int k = ; k < ml; ++k){
for (int v = ; v <= n; ++v){
if (par[k][v] == -) par[k + ][v] = -;
else par[k + ][v] = par[k][par[k][v]];
}
}
return ;
}
int lca(int u, int v)
{
if (dep[u] > dep[v]) swap(u, v);
for (int k = ; k < ml; ++k){
if (((dep[v] - dep[u]) >> k) & ) v = par[k][v];
}
if (u == v) return u;
for (int k = ml; k >= ; --k){
if (par[k][u] != par[k][v]) u = par[k][u], v = par[k][v];
}
return par[][u];
}
int main()
{
int s, u, v;
scanf("%d %d %d", &n, &m, &s);
int t = n;
while (--t){
scanf("%d %d", &u, &v);
g[u].push_back(v);
g[v].push_back(u);
}
init(s);
while (m--){
scanf("%d %d", &u, &v);
printf("%d\n", lca(u, v));
}
return ;
}
题目 https://www.luogu.org/problemnew/show/P3379
自己写的一个倍增LCA
#include<iostream>
#include<cstring>
//#include<bits/stdc++.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<cstdio>
#include<map>
#include<set>
#define si(a) scanf("%d",&a)
#define sl(a) scanf("%lld",&a)
#define sii(a,b) scanf("%d%d",&a,&b)
#define sll(a,b) scanf("%lld%lld",&a,&b)
#define queues priority_queue
#define mod 998244353
#define mem(a) memset(a,0,sizeof(a));
#define def(a) ((a)&(-a))
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
//priority_queue<int,vector<int >,greater<int > >q;
const ll INF=0x3f3f3f3f;
//const double E=exp(1);
//const double PI=acos(-1);
using namespace std;
int de[];
int lg[];
int f[][];
vector<int>ss[];
void get_lg()
{lg[]=-;
for(int i=;i<=;i++)
lg[i]=lg[i>>]+;
}
void dfs(int p,int fa)
{ de[p]=de[fa]+;
f[p][]=fa;
for(int i=;i<=lg[de[p]]+;i++)
f[p][i]=f[f[p][i-]][i-];
for(int i=;i<ss[p].size();i++)
{ int x=ss[p][i];
if(x!=fa)
{
dfs(x,p);
}
}
}
int LCA(int a,int b)
{ if(de[a]<de[b])swap(a,b);
while(de[a]!=de[b])
{
a=f[a][lg[de[a]-de[b]]];
}
if(a==b)return a;
for(int i=lg[de[a]];i>=;i--)
{
if(f[a][i]!=f[b][i])
a=f[a][i],b=f[b][i];
}
return f[a][];
}
int main()
{ ios::sync_with_stdio(false);
int n,m,s;
scanf("%d%d%d",&n,&m,&s);
for(int i=;i<n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
ss[a].pb(b);
ss[b].pb(a);
}
get_lg();
dfs(s,);
for(int i=;i<=n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",LCA(a,b));
// cout<<LCA(a,b)<<endl;
}
}
又有一个树链剖分求LCA
#include<bits/stdc++.h>
typedef long long ll;
const int maxn=+;
const int INF=0x3f3f3f3f;
using namespace std;
const ll MAX=
int read(){int x=,f=;char s=getchar();for(; s>''||s<''; s=getchar()) if(s=='-') f=-;for(; s>=''&&s<=''; s=getchar()) x=x*+s-'';return x*f;}
vector<int>q[maxn];
int f[maxn];
int d[maxn];
int siz[maxn];
int son[maxn]; int top[maxn];
int id[maxn];
int rk[maxn];
int dfs(int a,int fa)
{
f[a]=fa;
d[a]=d[fa]+;
siz[a]=;
for(int i=; i<q[a].size(); i++)
{
int z=q[a][i];
if(z!=fa)
{
dfs(z,a);
siz[a]+=siz[z];
if(!son[a]||siz[z]>siz[son[a]])
son[a]=z;
}
}
return ;
}
int sum;
void dfs1(int a,int b)
{
top[a]=b;
if(!son[a])
return ;
dfs1(son[a],b);
for(int i=; i<q[a].size(); i++)
{
int z=q[a][i];
if(z!=f[a]&&z!=son[a])
dfs1(z,z);
}
}
int lca(int a,int b)
{
while(top[a]!=top[b])
{
d[top[a]]>d[top[b]]?a=f[top[a]]:b=f[top[b]]; }
return d[a]<d[b]?a:b;
}
int main()
{
ios::sync_with_stdio(false);
int n,m,s;
n=read();m=read();s=read();
for(int i=; i<n; i++)
{
int a,b;
a=read();
b=read();
q[a].pb(b);
q[b].pb(a);
}
dfs(s,);
dfs1(s,s);
while(m--)
{
int a,b;
a=read();
b=read();
cout<<lca(a,b)<<endl;
}
}