题意:带环lca。
题解:lca
从入度为0的点开始dfs。
注意是有向边。
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<fstream>
#include<set>
#include<map>
#include<sstream>
#include<iomanip>
#define ll long long
#define pii pair<int, int>
using namespace std;
const int MAXN = 1e4 + 5;
int t, n, q;
vector<int> v[MAXN];
int fa[MAXN][31], dep[MAXN], ind[MAXN];
void init() {
for (int i = 1; i <= n; i++) v[i].clear(), ind[i] = 0;
// memset(fa, 0, sizeof(fa));
// memset(cost, 0, sizeof(cost));
// memset(dep, 0, sizeof(dep));
}
void dfs(int root, int fno) { //1 0
fa[root][0] = fno;
dep[root] = dep[fa[root][0]] + 1;
for (int i = 1; i < 31; ++i) {
fa[root][i] = fa[fa[root][i - 1]][i - 1];
}
int sz = v[root].size();
for (int i = 0; i < sz; ++i) {
if (v[root][i] == fno) continue;
dfs(v[root][i], root);
}
}
int lca(int x, int y) {
if (dep[x] > dep[y]) swap(x, y);
int tmp = dep[y] - dep[x];
for (int j = 0; tmp; ++j, tmp >>= 1)
if (tmp & 1) y = fa[y][j];
if (y == x) return x;
for (int j = 30; j >= 0 && y != x; --j) {
if (fa[x][j] != fa[y][j]) {
x = fa[x][j];
y = fa[y][j];
}
}
return fa[x][0];
}
int main() {
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
init();
int x, y;
for (int i = 1; i < n; i++) {
scanf("%d%d", &x, &y);
v[x].push_back(y);
//v[y].push_back(x);
ind[y]++;
}
for (int i = 1; i <= n; i++) {
if (ind[i] == 0) {
dfs(i, 0);
break;
}
}
scanf("%d%d", &x, &y);
printf("%d\n", lca(x, y));
}
return 0;
}