• LCA 算法(一)ST表


    介绍一种解决最近公共祖先的在线算法,st表,它是建立在线性中的rmq问题之上。

     

    代码:

     

      1 //LCA: DFS+ST(RMQ)
      2 
      3 #include<cstdio>
      4 #include<cctype>
      5 #include<iostream>
      6 using namespace std;
      7 
      8 const int size=500010;
      9 int n,m,s,tot;
     10 int first[size],log[size<<1],f[size<<1][60],head[size<<1],p[size<<1][60];
     11 bool vis[size];
     12 struct node1
     13 {
     14     int path,depth;
     15 }a[size*2];
     16 struct node2
     17 {
     18     int next,to;
     19 }e[size*2];
     20 
     21 inline int read()
     22 {
     23     int x=0,f=1;
     24     char c=getchar();
     25     while (!isdigit(c))
     26         f=c=='-'?-1:1,c=getchar();
     27     while (isdigit(c))
     28         x=(x<<1)+(x<<3)+(c^48),c=getchar();
     29     return x*f;
     30 }
     31 
     32 inline int write(int x)
     33 {
     34     if (x<0)
     35         x=-x;
     36     if (x>9)
     37         write(x/10);
     38     putchar(x%10+48);
     39 }
     40 
     41 inline void add(int from,int to)
     42 {
     43     ++tot;
     44     e[tot].to=to;
     45     e[tot].next=head[from];
     46     head[from]=tot;
     47 }
     48 
     49 inline void logn()
     50 {
     51     int i;
     52     log[0]=-1;
     53     for (i=1;i<=n*2+1;i++)
     54         log[i]=log[(i>>1)]+1;
     55 }
     56 
     57 inline void DFS(int x,int dep)
     58 {
     59     a[++tot].path=x;
     60     a[tot].depth=dep;
     61     first[x]=tot;
     62     vis[x]=true;
     63     for (int i=head[x];i;i=e[i].next)
     64         if (!vis[e[i].to])
     65         {
     66             DFS(e[i].to,dep+1);
     67             a[++tot].path=x;
     68             a[tot].depth=dep;
     69         }
     70 }
     71 
     72 inline void ST()
     73 {
     74     int i,j;
     75     for (i=1;i<=tot;i++)
     76         f[i][0]=i;
     77     for (j=1;j<=log[tot];j++)
     78         for (i=1;i+(1<<j)<=tot;i++)
     79         {
     80             if (a[f[i][j-1]].depth<a[f[i+(1<<j-1)][j-1]].depth)
     81                 f[i][j]=f[i][j-1];
     82             else
     83                 f[i][j]=f[i+(1<<j-1)][j-1];
     84         }
     85 }
     86 
     87 inline int RMQ(int l,int r)
     88 {
     89     int w=log[r-l+1];
     90     return a[f[l][w]].depth<a[f[r-(1<<w)+1][w]].depth?f[l][w]:f[r-(1<<w)+1][w];
     91 }
     92 
     93 inline int LCA(int u,int v)
     94 {
     95     int x=first[u],y=first[v];
     96     if (x>y)
     97         swap(x,y);
     98     return a[RMQ(x,y)].path;
     99 }
    100 
    101 int main()
    102 {
    103     int i,j,x,y;
    104     n=read();
    105     m=read();
    106     s=read();
    107     logn();
    108     for (i=1;i<n;i++)
    109     {
    110         x=read();
    111         y=read();
    112         add(x,y);
    113         add(y,x);
    114     }
    115     tot=0;
    116     DFS(s,1);
    117     ST();
    118     while (m--)
    119     {
    120         x=read();
    121         y=read();
    122         write(LCA(x,y));
    123         putchar(10);
    124     }
    125     return 0;
    126 }
  • 相关阅读:
    比特币的加密算法
    区块链项目-Lisk
    以太坊(二)
    以太坊的货币发行模式
    以太坊(一)
    前端er们如何最快开发h5移动端页面?
    jQuery Ajax常用总结
    js中变量作用域
    网页引入特殊字体的几种方案
    几个有趣的WEB设备API(二)
  • 原文地址:https://www.cnblogs.com/Ronald-MOK1426/p/8999211.html
Copyright © 2020-2023  润新知