LCA模板题 POJ1330

使用了倍增的LCA,有时间再去学Tarjan

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
const int maxn=10010;
const int maxm=60;
int t,i,j,k,tot=0,n,m;
struct seg{int x,next;}v[maxn];
int dp[maxn][maxm],d[maxn],base[maxn],f[maxn];
int add(int x,int y)
   {  v[++tot].x=y;   
      v[tot].next=base[x];
      base[x]=tot;
      }
int dfs(int x)
   {  for (int i=1;i<=k;i++) 
         dp[x][i]=dp[dp[x][i-1]][i-1];
         for (int i=base[x];i;i=v[i].next)
         d[v[i].x]=d[x]+1,dfs(v[i].x);
     }
int swap(int &x,int &y)
   {   int tmp=y;
       y=x;
       x=tmp;}

int lca(int x,int y)
   {   if (d[x]<d[y]) swap(x,y);
       for (int i=k;i>=0;i--)
       if (d[dp[x][i]]>=d[y]) x=dp[x][i];
       if (x==y) return x;
       for (int i=k;i>=0;i--)
            if (dp[x][i]!=dp[y][i])
            x=dp[x][i],y=dp[y][i];
       return dp[x][0];
     }

int main()
{  //freopen("1.in","r",stdin);
   scanf("%d",&t); 
   while (t--)
      {   scanf("%d",&n);  tot=0;
          k=30;
          memset(v,0,sizeof(v));
          memset(base,0,sizeof(base));
          memset(dp,0,sizeof(dp));
          memset(f,0,sizeof(f));
          memset(d,0,sizeof(d));
          int x,y;
          for (int i=1;i<=n-1;i++)
           {scanf("%d%d",&x,&y);add(x,y);f[y]=x;dp[y][0]=x;}
         for (int i=1;i<=n;i++)
              if (f[i]==0) ,d[i]=1,dfs(i);
     scanf("%d%d",&x,&y);
     printf("%d
",lca(x,y));}

 }
View Code
原文地址:https://www.cnblogs.com/williamchenwl/p/3645324.html