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 }

猜你喜欢

转载自www.cnblogs.com/Ronald-MOK1426/p/8999211.html