LCA 问题,因为查询操作很少,这次使用离线的Tarjan算法
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <utility>
#include <stack>
#include <vector>
#include <cstring>
#define WHITE -1
#define BLACK 0
using namespace std;
const int maxn= 1e4+3;
vector<vector<int> > fa;
int cl[maxn], mk[maxn];
int qa, qb;
int dad[maxn];
int nca;
void Init(int n)
{
fa.clear();
fa.resize(n+3);
memset(cl, WHITE, sizeof(cl));
memset(mk, -1, sizeof(mk));
}
int Find(int a)
{
if (a== dad[a]){
return dad[a];
}
return dad[a]= Find(dad[a]);
}
void Union(int a, int b)
{
a= Find(a);
b= Find(b);
if (a== b){
return;
}
if (mk[b]< mk[a]){
dad[a]= dad[b];
}
else{
dad[b]= dad[a];
}
}
void dfs(int u, int d)
{
int sn;
mk[u]= d;
dad[u]= u;
for (int i= 0; i< int(fa[u].size()); ++i){
sn= fa[u][i];
dfs(sn, d+1);
dad[sn]= u;
}
if (u==qa && BLACK== cl[qb]){
nca= Find(qb);
return;
}
if (u== qb && BLACK== cl[qa]){
nca= Find(qa);
return;
}
cl[u]= BLACK;
}
int main(void)
{
int T, n;
int nd, snd, rt;
scanf("%d", &T);
while (T--){
scanf("%d", &n);
Init(n);
for (int i= 0; i< n-1; ++i){
scanf("%d %d", &nd, &snd);
fa[nd].push_back(snd);
mk[snd]= 0;
}
scanf("%d %d", &qa, &qb);
for (int i= 1; i<= n; ++i){
if (mk[i]){
rt= i;
break;
}
}
dfs(rt, 1);
printf("%d
", nca);
}
return 0;
}