LCA 板子题。。。自己写了一个练练手。。。发现还可以。。
直接上AC 代码了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int maxn = 1e6+5;
struct node
{
int to,nxt;
}ed[maxn*2];
int tot,head[maxn];
int n,m,s;
void add(int u,int v)
{
ed[++tot].to = v;
ed[tot].nxt = head[u];
head[u] = tot;
}
int f[maxn][25],deep[maxn];
int ans[maxn];
void dfs(int u,int p,int d)
{
f[u][0] = p;
deep[u] = d;
for(int i=head[u];i;i=ed[i].nxt)
{
if(ed[i].to != p)
dfs(ed[i].to, u, d+1);
}
}
void init()
{
dfs(s, -1, 1);
for(int i=0;i<19;i++)
{
for(int u=1;u<=n;u++)
{
if(f[u][i] < 0)
f[u][i+1] = -1;
else
f[u][i+1] = f[f[u][i]][i];
}
}
}
int lca(int a,int b)
{
if(deep[a] > deep[b])
swap(a,b);
for(int i=0;i<20;i++)
{
if(deep[a] == deep[b])
break;
if((deep[b] - deep[a])>>i&1)
b = f[b][i];
}
if(a==b)
return a;
for(int i=19;i>=0;i--)
{
if(f[a][i] != f[b][i])
{
a = f[a][i];
b = f[b][i];
}
}
return f[a][0];
}
int main()
{
scanf("%d%d%d",&n,&m,&s);
for(int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
init();
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",lca(x,y));
}
return 0;
}