倍增算法(在线)
#include<iostream>
#include<math.h>
#include<string.h>
#define MAXN 10005
using namespace std;
int head[MAXN*2],cnt;
struct edge {
int to;
int next;
} e[MAXN*2];
int N,d[MAXN],f[MAXN][30],n;
void init() {
N=(int)(log(n)/log(2));
cnt=0;
for(int i=0; i<MAXN; i++) {
head[i]=-1;
}
memset(f,0,sizeof(f));
}
void add(int u,int v) {
e[cnt].to=v;
e[cnt].next=head[u];
head[u]=cnt++;
}
void dfs(int u,int fa,int dep) {
d[u]=dep;
f[u][0]=fa;
for(int i=1; i<=N; i++) {
f[u][i]=f[f[u][i-1]][i-1];
}
for(int i=head[u]; i!=-1; i=e[i].next) {
int v=e[i].to;
if(v==fa)continue;
dfs(v,u,dep+1);
}
}
int lca(int a,int b) {
if(d[a]>d[b]) {
swap(a,b);
}
for(int i=N; i>=0; i--) {
if(d[f[b][i]]>=d[a]) {
b=f[b][i];
}
}
if(a==b)return a;
for(int i=N; i>=0; i--) {
if( f[a][i] != f[b][i]) {
a=f[a][i];
b=f[b][i];
}
}
return f[a][0];
}
int main() {
int t;
cin>>t;
while(t--) {
cin>>n;
init();
for(int i=1; i<n; i++) {
int a,b;
cin>>a>>b;
add(a,b);
f[b][0]=a;
}
for(int i=1; i<n; i++) {
if(f[i][0]==0) {
dfs(i,0,1);
break;
}
}
int a,b;
cin>>a>>b;
cout<<lca(a,b)<<endl;
}
}
Tarjan算法 (离线)
#include<iostream>
#include<math.h>
#include<string.h>
#define MAXN 10005
using namespace std;
int head[MAXN*2],cnt;
bool vis[MAXN];
bool is_root[MAXN];
int f[MAXN];
int sox,soy,ans;
struct edge {
int to;
int next;
} e[MAXN*2];
void add(int u,int v) {
e[cnt].to=v;
e[cnt].next=head[u];
head[u]=cnt++;
}
void init() {
cnt=0;
for(int i=0; i<MAXN; i++) {
head[i]=-1;
f[i]=i;
}
memset(vis,false,sizeof(vis));
memset(is_root,true,sizeof(is_root));
}
int find(int x) {
if(x!=f[x])
f[x]=find(f[x]);
return f[x];
}
void join(int x,int y) {
int fx=find(x),fy=find(y);
if(fx!=fy)
f[fy]=fx;
}
void lca(int u){
for(int i=head[u]; i!=-1; i=e[i].next) {
int v=e[i].to;
lca(v);
join(u,v);
vis[v]=true;
}
if(sox==u &&vis[soy] ){
ans=find(soy);
}
if(soy==u &&vis[sox] ){
ans=find(sox);
}
}
int main() {
int t;
cin>>t;
while(t--) {
init();
int n;
cin>>n;
for(int i=1; i<n; i++) {
int a,b;
cin>>a>>b;
add(a,b);
is_root[b]=false;
}
int root;
for(int i=1; i<=n; i++){
if(is_root[i]==true)
root=i;
}
cin>>sox>>soy;
lca(root);
cout<<ans<<endl;
}
}