裸的lca,找最近公共祖先, 他给你了父亲节点,只要根据给的数据建树就可以了。
这个题写的时候出了bug,dfs() 的时候,树的顶端的父亲节点是否设成语顶端一样。如果一样,dep可以memset(dep,0)
如果不一样,那么,dep 的值 ,顶端的节点和 父亲节点的dep 一定不能一样。如果顶端值为0,,其父亲节点一定不能为0
否则出bug
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#define mem(x,v) memset(x,v,sizeof(x))
#define rep(i,a,b) for (int i = a; i < b; i++)
#define per(i,a,b) for (int i = a; i > b; i--)
using namespace std;
typedef long long LL;
const double EPS = 1e-10;
const int INF = 0x3f3f3f3f;
const int N = 2e4+10;
int n,in[N];
int f[N][20],dep[N];
int Head[N],cnt,p[N],Next[N];
void Add(int u, int v){
cnt++;
Next[cnt] = Head[u];
Head[u] = cnt;
p[cnt] = v;
return;
}
void dfs(int u, int fa, int deep){
f[u][0] = fa;
dep[u] = deep;
for (int i = 1; i < 20; i++)
f[u][i] = f[f[u][i-1]][i-1];
for (int i = Head[u]; i != -1; i = Next[i]){
int v = p[i];
if (v == fa) continue;
dfs(v,u,deep+1);
}
return;
}
int lca(int x, int y){
if (dep[x] < dep[y]) swap(x,y);
per(i,19,-1)
if (dep[f[x][i]] >= dep[y]) x = f[x][i];
if (x == y) return x;
per(i,19,-1)
if (f[x][i] != f[y][i]) {
x = f[x][i];
y = f[y][i];
}
return f[x][0];
}
int main(){
int T;
cin>>T;
while(T--){
mem(in,0); mem(Head,-1); cnt = -1;
scanf("%d",&n);
rep(i,1,n){
int x,y;
scanf("%d%d",&x,&y);
Add(x,y);
in[y]++;
}
int s;
rep(i,1,n+1) if (in[i] == 0) {
s = i; break;
}
mem(f,0); mem(dep,-1);
dfs(s,0,0); //这个地方出了bug
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",lca(x,y));
}
return 0;
}