Tarjan 离线求LCA

#include<bits/stdc++.h>
using namespace std;
const int maxn=450005;
struct node{
    int nxt;
    int to;
}tree[maxn*2];
struct node1{
    int LCA;
    int nxt;
    int to;
}qtree[maxn*2];
int fa[maxn];
int n,m,p,x,y,t;
int cnt1,cnt2,head1[maxn],head2[maxn];
int vis[maxn];
void add1(int x,int y){
    tree[++cnt1].nxt=head1[x];
    tree[cnt1].to=y;
    head1[x]=cnt1;
}
void add2(int x,int y){
    qtree[++cnt2].nxt=head2[x];
    qtree[cnt2].to=y;
    head2[x]=cnt2;
}
int find(int x){
    if(x!=fa[x]) fa[x]=find(fa[x]);
    return fa[x];
}
void dfs(int x){
    vis[x]=1;
    for(int i=head1[x];i;i=tree[i].nxt){
        int v=tree[i].to;
        if(vis[v]){
            continue;
        }
        dfs(v);
        fa[v]=x;
    }     
    for(int i=head2[x];i;i=qtree[i].nxt){
        int v=qtree[i].to;
        if(vis[v]){
            qtree[i].LCA=find(v);
            if(i%2) {
                qtree[i+1].LCA=qtree[i].LCA;
            }
            else qtree[i-1].LCA=qtree[i].LCA;
        }
    }
}
int rt;
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        fa[i]=i;
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&t);
        if(!t) rt=i;
        add1(i,t);
        add1(t,i);
    }
    scanf("%d",&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d",&x,&y);
        add2(x,y);
        add2(y,x);
    }
    dfs(rt);
    for(int i=1;i<=m;i++){
        printf("%d
",qtree[i*2].LCA);
    }
    return 0; 
}
原文地址:https://www.cnblogs.com/LJB666/p/11017472.html