zoukankan      html  css  js  c++  java
  • poj 1330 LCA (倍增+离线Tarjan)

    /*
    先来个倍增 
    */
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define maxn 10010
    using namespace std;
    int T,n,num,head[maxn],st,end,anc,fa[maxn][25],dep[maxn],out[maxn],root;
    struct node
    {
        int u,v,t,pre;
    }e[maxn*2];
    void Add(int from,int to)
    {
        num++;
        e[num].u=from;
        e[num].v=to;
        e[num].pre=head[from];
        head[from]=num;
    }
    void Dfs(int now,int from,int c)
    {
        fa[now][0]=from;
        dep[now]=c;
        for(int i=head[now];i;i=e[i].pre)
          if(e[i].v!=from)
            Dfs(e[i].v,now,c+1);
    }
    void Get_fa()
    {
        for(int j=1;j<=16;j++)
          for(int i=1;i<=n;i++)
            fa[i][j]=fa[fa[i][j-1]][j-1];
    }
    int Get_same(int a,int t)
    {
        for(int i=1;i<=t;i++)
          a=fa[a][0];
        return a;
    }
    int LCA(int a,int b)
    {
        if(dep[a]<dep[b])swap(a,b);
        a=Get_same(a,dep[a]-dep[b]);
        if(a==b)return a;
        for(int i=16;i>=0;i--)
          if(fa[a][i]!=fa[b][i])
            {
              a=fa[a][i];b=fa[b][i];
            }
        return fa[a][0];
    }
    int main()
    {
        scanf("%d",&T);
        while(T--)
          {
              memset(head,0,sizeof(head));
              memset(fa,0,sizeof(fa)); 
              memset(out,0,sizeof(out));
              memset(dep,0,sizeof(dep));
              num=0;root=0;
              scanf("%d",&n);
              int x,y;
              for(int i=1;i<=n-1;i++)
                {
                    scanf("%d%d",&x,&y);
                    Add(x,y);Add(y,x);
                    out[y]=1;
              }
            for(int i=1;i<=n;i++)
              if(out[i]==0)root=i;
            Dfs(root,root,0);
            Get_fa();
            scanf("%d%d",&st,&end);
            anc=LCA(st,end);
            printf("%d
    ",anc);
          }
        return 0;
    }
    /*
    离线Tarjan 
    我们Dfs整张图的时候 对于一组u v 
    我们一定按照 u s v 的顺序跑完 
    此时u v 在以s为根的子树里 
    那么我们借助并茶几 将u v的fa 的anc赋值为s
    这样我们查询u v 的时候就能找到s 
    如果我们求 st end 的lca
    当我们遍历到st 或者end的时候 只需要判断另一个是不是已经被访问过 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #define maxn 100010
    using namespace std;
    int T,n,m,fa[maxn],st,end,anc[maxn];
    vector<int>a[maxn];
    int root[maxn],f[maxn];
    void init()
    {
        scanf("%d",&n);
        int x,y;
        for(int i=1;i<=n;i++)
          {
              fa[i]=i;root[i]=1;
          }
        for(int i=1;i<=n-1;i++)
          {
              scanf("%d%d",&x,&y);
              a[x].push_back(y);
              fa[y]=x;root[y]=0;
          }
    }
    int find(int x)
    {
        if(x!=fa[x])fa[x]=find(fa[x]);
        return fa[x];
    }
    void Union(int x,int y)
    {
        int r1=find(x);
        int r2=find(y);
        if(r1!=r2)fa[r2]=r1;
    }
    void LCA(int parent)
    {
        anc[parent]=parent;//初始化自己的lca为自己 
        for(int i=0;i<a[parent].size();i++)
          {
              LCA(a[parent][i]);
              Union(parent,a[parent][i]);
              anc[find(parent)]=parent;//把自己和自己子孙们的lca赋值为它  
          }
        f[parent]=1;
        if(st==parent&&f[end]==1)
          {
              printf("%d
    ",anc[find(end)]);
              return;
          }
        if(end==parent&&f[st]==1)
          {
              printf("%d
    ",anc[find(st)]);
              return;
          }
    }
    int main()
    {
        scanf("%d",&T);
        while(T--)
          {
              memset(f,0,sizeof(f));
              memset(a,0,sizeof(a));
              init();
              scanf("%d%d",&st,&end);
            for(int i=1;i<=n;i++)
              if(root[i])
                LCA(i);
          }
        return 0;
    }
  • 相关阅读:
    (转)前端开发框架选型清单
    (转)关于java和web项目中的相对路径问题
    (转)phonegap 数据库详解
    (转)SQLite数据库增删改查操作
    (转)JS中innerHTML,innerText,value
    (转)js函数参数设置默认值
    (转)HTML5开发学习(2):本地存储之localStorage 、sessionStorage、globalStorage
    (转)HTML5开发学习(3):本地存储之Web Sql Database
    [笔记]普通平衡树(Splay)
    [笔记][题解]树链剖分&lgP3384
  • 原文地址:https://www.cnblogs.com/yanlifneg/p/5546115.html
Copyright © 2011-2022 走看看