http://code.bupt.edu.cn/problem/p/257/
最近公共祖先LCA的离线Tarjan模板
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <stack>
#include <deque>
#include <vector>
#include <bitset>
#include <cmath>
#include <utility>
#define Maxn 100005
#define Maxm 1000005
#define lowbit(x) x&(-x)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define PI acos(-1.0)
#define make_pair MP
#define LL long long
#define Inf (1LL<<62)
#define inf 0x3f3f3f3f
#define re freopen("in.txt","r",stdin)
#define wr freopen("out.txt","w",stdout)
using namespace std;
int p[Maxn];
int head[Maxn];
int qhead[Maxn];
int ancestor[Maxn];
int ans[Maxn];
int k,kk;
bool vis[Maxn];
int find(int x)
{
return p[x]==-1?x:p[x]=find(p[x]);
}
void _union(int u,int v)
{
int t1=find(u);
int t2=find(v);
if(t1!=t2)
p[t2]=t1;
}
struct Edge
{
int to;
int next;
}edge[Maxm];
void addedge(int u,int v)
{
edge[k].to=v;
edge[k].next=head[u];
head[u]=k++;
}
struct Query
{
int q,next;
int index;
}query[Maxn];
void add_query(int u,int v,int index)
{
query[kk].q=v;
query[kk].next=qhead[u];
query[kk].index=index;
qhead[u]=kk++;
query[kk].q=u;
query[kk].next=qhead[v];
query[kk].index=index;
qhead[v]=kk++;
}
void init()
{
k=kk=0;
memset(head,-1,sizeof(head));
memset(qhead,-1,sizeof(qhead));
memset(p,-1,sizeof(p));
memset(ancestor,0,sizeof(ancestor));
memset(vis,false,sizeof(vis));
}
void LCA(int u)
{
ancestor[u]=u;
vis[u]=true;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(vis[v])
continue;
LCA(v);
_union(u,v);
ancestor[find(u)]=u;
}
for(int i=qhead[u];i!=-1;i=query[i].next)
{
int v=query[i].q;
if(vis[v])
ans[query[i].index]=ancestor[find(v)];
}
}
int main()
{
//re;
//wr;
int T,u,v,m,n;
scanf("%d",&T);
while(T--)
{
init();
scanf("%d",&n);
for(int i=1;i<n;i++)
{
scanf("%d %d",&u,&v);
addedge(u,v);
}
scanf("%d",&m);
for(int i=0;i<m;i++)
{
scanf("%d %d",&u,&v);
add_query(u,v,i);
}
LCA(1);
for(int i=0;i<m;i++)
printf("%d\n",ans[i]);
}
return 0;
}