题目链接:点击查看
题意:求最近公共祖先
题解:树上倍增模板->点击查看
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 10010;
int n, m;
vector<int> v[N];
int f[N][110], dep[N], in[N];
void dfs(int u) {
for(int i = 0; i < m; i++)
if(f[u][i - 1])
f[u][i] = f[f[u][i - 1]][i - 1];
for(int i = 0;i < v[u].size(); i++)
{
int to =v[u][i];
if(to != f[u][0]) {
f[to][0] = u;
dep[to] = dep[u] + 1;
dfs(to);
}
}
}
int LCA(int x, int y) {
if(dep[x] < dep[y]) swap(x, y);
int cnt = dep[x] - dep[y];
for(int i = 0; i < m; i++)
if((1 << i) & cnt)
x = f[x][i];
if(x == y) return x;
for(int i = m; i >= 0; i--) {
if(f[x][i] != f[y][i]) {
x = f[x][i];
y = f[y][i];
}
}
return f[x][0];
}
int main() {
int T;
int x, y;
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
m = (int)log2(n);
for(int i = 0; i <= n; i++)
{
v[i].clear();
in[i] = 0;
for(int j = 0; j < m; j++)
f[i][j] = 0;
}
for(int i = 0; i <= n;i++)
for(int j = 0; j < m; j++)
f[i][j] = 0;
for(int i = 1; i < n; i++) {
scanf("%d %d", &x, &y);
v[x].push_back(y);
in[y]++;
}
int id;
for(int i = 1; i <= n; i++)
if(!in[i]) {
id = i;
break;
}
// cout<<id<<endl;
dfs(id);
scanf("%d %d", &x, &y);
printf("%d\n", LCA(x, y));
}
return 0;
}