洛谷——P3379 【模板】最近公共祖先(LCA)

题目链接

Tarjan

#include<bits/stdc++.h>
using namespace std;
const int maxn=5e6+5;
struct node
{
   int v,index,next;
   node(){}
   node(int a,int b,int c)
   {
      index=a;
      v=b;
      next=c;
   }
};
int N,M,S,cnt,qcnt;
node query[maxn<<1],edge[maxn<<1];
int ans[maxn],fa[maxn],vis[maxn],head[maxn],qhead[maxn];
void tarjan(int s,int pre);
int find(int p);
void add(int i,int from,int to);
void qadd(int i,int from,int to);
int main() 
{
   fill(fa,fa+maxn,-1);
   fill(head,head+maxn,-1);
   fill(qhead,qhead+maxn,-1);
   int i,from,to;
   scanf("%d%d%d",&N,&M,&S);
   for(i=1;i<N;i++)
   {
      scanf("%d%d",&from,&to);
      add(0,from,to);
      add(0,to,from);
   }

   for(i=0;i<M;i++)
   {
      scanf("%d%d",&from,&to);
      qadd(i,from,to);
      qadd(i,to,from);
   }

   tarjan(S,-1);
   
   for(i=0;i<M;i++)
      printf("%d
",ans[i]);
   
   system("pause");
   return 0;
}
void add(int i,int from,int to)
{
   edge[cnt]=node(i,to,head[from]);
   head[from]=cnt++;
}
void qadd(int i,int from,int to)
{
   query[qcnt]=node(i,to,qhead[from]);
   qhead[from]=qcnt++;
}
int find(int p)
{
   return fa[p]==-1?p:fa[p]=find(fa[p]);
}
void tarjan(int s,int pre)
{
   int i,p;
   for(i=head[s];i!=-1;i=edge[i].next)
   {
      p=edge[i].v;
      if(p==pre) continue;
      tarjan(p,s);
      fa[p]=s;
   }
   vis[s]=1;
   for(i=qhead[s];i!=-1;i=query[i].next)
   {
      if(vis[query[i].v])
         ans[query[i].index]=find(query[i].v);
   }
}

ST

#include<bits/stdc++.h>
using namespace std;
const int maxn=500005;
struct node
{
   int v,next;
   node(){}
   node(int a,int b)
   {v=a;next=b;}
};
node edge[maxn<<1];
int N,M,S,head[maxn],deep[maxn],st[maxn][20],cnt;
void add(int from,int to);
void dfs(int p,int pre);
int lca(int u,int v);
int main()
{
   int a,b,i;
   fill(head,head+maxn,-1);
   scanf("%d%d%d",&N,&M,&S);
   for(i=1;i<N;i++)
   {
      scanf("%d%d",&a,&b);
      add(a,b);
      add(b,a);
   }
   dfs(S,0);
   for(i=0;i<M;i++)
   {
      scanf("%d%d",&a,&b);
      printf("%d
",lca(a,b));
   }
   system("pause");
   return 0;
}
void add(int from,int to)
{
   edge[cnt]=node(to,head[from]);
   head[from]=cnt++;
}
void dfs(int p,int pre)
{
   int i;

   deep[p]=deep[pre]+1;
   st[p][0]=pre;
   for(i=1;(1<<i)<=deep[p];i++)
      st[p][i]=st[st[p][i-1]][i-1];
   
   for(i=head[p];i!=-1;i=edge[i].next)
   {
      if(edge[i].v==pre) continue;
      dfs(edge[i].v,p);
   }
}
int lca(int u,int v)
{
   int i;
   if(deep[u]!=deep[v])
   {
      if(deep[u]<deep[v])  swap(u,v);
      for(i=19;i>=0;i--)
      {
         if(deep[st[u][i]]>=deep[v])
            u=st[u][i];
      }
   }
   if(u==v) return u;
   for(i=19;i>=0;i--)
   {
      if(st[u][i]!=st[v][i])
      {
         u=st[u][i];
         v=st[v][i];
      }
   }
   return st[u][0];
}