先上传送门:P3379 【模板】最近公共祖先(LCA) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P3379
最近公共祖先可以和很多点结合,比如和最小生成树(毒瘤):
P3366 【模板】最小生成树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P3366最近公共祖先一般都采用倍增优化:
import java.io.*;
import java.util.*;
public class Main {
static int maxn=500001; // also maxm
static int n,m,s,cnt;
static int[] vv=new int[maxn<<1],to=new int[maxn<<1],he=new int[maxn<<1];
static int[] lg=new int[maxn],depth=new int[maxn];
static int[][] fa = new int[maxn][22];
public static void main(String[] args) throws IOException {
n=nextInt();m=nextInt();s=nextInt();
for(int i=1;i<=n;i++)
lg[i]=lg[i-1]+(1<<lg[i-1]==i?1:0);
for(int i=1;i<n;i++){
int x=nextInt(),y=nextInt();
addEdge(x,y);
addEdge(y,x);
}
dfs(s,0);
for(int i=1;i<=m;i++){
int x=nextInt(),y=nextInt();
int ans=lca(x,y);
out.println(ans);
}
out.flush();
}
public static void dfs(int now,int fath){
fa[now][0]=fath;depth[now]=depth[fath]+1;
for(int i=1;i<=lg[depth[now]];i++)
fa[now][i]=fa[fa[now][i-1]][i-1];
for(int i=he[now];i>0;i=to[i])
if(vv[i]!=fath) dfs(vv[i],now);
}
public static int lca(int x,int y){
if(depth[x]<depth[y]) {int tmp=x;x=y;y=tmp;}
while(depth[x]>depth[y])
x=fa[x][lg[depth[x]-depth[y]]-1];
if(x==y) return x;
for(int k=lg[depth[x]]-1;k>=0;k--)
if(fa[x][k]!=fa[y][k]){
x=fa[x][k];y=fa[y][k];
}
return fa[x][0];
}
public static void addEdge(int u,int v){
vv[++cnt]=v;
to[cnt]=he[u];
he[u]=cnt;
}
static StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
static PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
static int nextInt() throws IOException {
in.nextToken();
return (int)in.nval;
}
}