ST表求LCA

复习一下

几个地方需要注意,lg2 数组要预处理,s数组是遍历顺序(不要手残打成DFS序)

#include <bits/stdc++.h>
using namespace std;

const int N = 2000005;
vector <int> g[N];
int n,m,rt,st[N][20],dep[N],dis[N],vis[N],ind,lg2[N],s[N],bg[N],ed[N];

void dfs(int p) {
    vis[p]=1;
    s[++ind]=p;
    bg[p]=ind;
    for(int q:g[p]) {
        if(vis[q]==0) {
            dep[q]=dep[p]+1;
            dfs(q);
            s[++ind]=p;
        }
    }
    ed[p]=ind;
}

int lca(int p,int q) {
    p=bg[p]; q=bg[q];
    if(p>q) swap(p,q);
    int l=lg2[q-p+1];
    int x=st[p][l];
    int y=st[q-(1<<l)+1][l];
    return dis[x]<dis[y]?x:y;
}

signed main() {
    ios::sync_with_stdio(false);
    scanf("%d%d%d",&n,&m,&rt);
    for(int i=0;i<=20;i++) for(int j=1<<i;j<1<<(i+1);j++) lg2[j]=i;
    for(int i=1;i<n;i++) {
        int t1,t2;
        scanf("%d%d",&t1,&t2);
        g[t1].push_back(t2);
        g[t2].push_back(t1);
    }
    dfs(rt);
    for(int i=1;i<=ind;i++) dis[i]=dep[s[i]];
    for(int i=1;i<=ind;i++) st[i][0]=i;
    for(int i=1;i<=19;i++) {
        for(int j=1;j<=ind;j++) {
            st[j][i]=dis[st[j][i-1]]<dis[st[j+(1<<(i-1))][i-1]]?
                    st[j][i-1]:st[j+(1<<(i-1))][i-1];
        }
    }
    for(int i=1;i<=m;i++) {
        int t1,t2;
        scanf("%d%d",&t1,&t2);
        printf("%d\n",s[lca(t1,t2)]);
    }
}

猜你喜欢

转载自www.cnblogs.com/mollnn/p/12441246.html