• 洛谷——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];
    }
  • 相关阅读:
    c++ Knight Moves 超级升级版
    百度招聘彩蛋
    C++ 八数码问题宽搜
    c++ 动态规划(数塔)
    c++ 深度优先搜索(迷宫)
    c++ 宽搜(倒水)
    c++ matrix逆时针螺旋
    c++ 基数排序
    c++ 二分答案(解方程)
    c++ 二分答案(数组查找)
  • 原文地址:https://www.cnblogs.com/VividBinGo/p/12259264.html
Copyright © 2020-2023  润新知