zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    #1071 : 小玩具
    #1063 : 缩地
    #1124 : 好矩阵
    hiho#1145 : 幻想乡的日常
    hiho#14
    hiho 毁灭者问题
    西南民大oj(递推)
    西南民大oj(矩阵快速幂)
    西南民大oj(两园交求面积)
    hdu2844(多重背包)
  • 原文地址:https://www.cnblogs.com/williamchenwl/p/3645324.html
Copyright © 2011-2022 走看看