【图论】树上最近公共祖先

int dis[200005];
int fa[200005][20];
 
void dfslca(int u, int p) {
    dis[u] = dis[p] + 1;
    fa[u][0] = p;
    for(int i = 1; i < 20; ++i)
        fa[u][i] = fa[fa[u][i - 1]][i - 1];
    for(int v : G[u]) {
        if(v == p)
            continue;
        dfslca(v, u);
    }
}
 
int lift(int x, int D) {
    for(int i = 20 - 1; i >= 0; --i) {
        if(dis[fa[x][i]] >= D)
            x = fa[x][i];
    }
    return x;
}

int lca(int x, int y) {
    if(dis[x] < dis[y])
        swap(x, y);
    for(int i = 20 - 1; i >= 0; --i) {
        if(dis[fa[x][i]] >= dis[y])
            x = fa[x][i];
    }
    if(x == y)
        return x;
    for(int i = 20 - 1; i >= 0; --i) {
        if(fa[x][i] != fa[y][i]) {
            x = fa[x][i];
            y = fa[y][i];
        }
    }
    return fa[x][0];
}

重链剖分

struct TreeChain {

    static const int MAXN = 100000 + 10;

    struct Edge {

        struct EdgeNode {
            int v, nxt;
        } en[MAXN << 1];

        int h[MAXN], top;

        void Init(int n) {
            top = 0;
            memset(h, 0, sizeof(h[0]) * (n + 1));
        }

        void Add(int u, int v) {
            en[++top] = {v, h[u]}, h[u] = top;
            en[++top] = {u, h[v]}, h[v] = top;
        }

    } edge;

    int dep[MAXN], siz[MAXN], mch[MAXN], pat[MAXN];
    int top[MAXN], tid[MAXN], cnt;

    void Init(int r) {
        edge.Init(n);
        for(int i = 1, u, v; i <= n - 1; ++i) {
            scanf("%d%d", &u, &v);
            edge.Add(u, v);
        }
        cnt = 0;
        dfs1(r, 0);
        dfs2(r, r);
    }

    void dfs1(int u, int p) {
        dep[u] = dep[p] + 1, siz[u] = 1, mch[u] = 0, pat[u] = p;
        for(int i = edge.h[u]; i; i = edge.en[i].nxt) {
            int v = edge.en[i].v;
            if(v == p)
                continue;
            dfs1(v, u);
            siz[u] += siz[v];
            if(mch[u] == 0 || siz[v] > siz[mch[u]])
                mch[u] = v;
        }
    }

    void dfs2(int u, int t) {
        top[u] = t, tid[u] = ++cnt;
        if(mch[u] != 0)
            dfs2(mch[u], t);
        for(int i = edge.h[u]; i; i = edge.en[i].nxt) {
            int v = edge.en[i].v;
            if(v == pat[u] || v == mch[u])
                continue;
            dfs2(v, v);
        }
    }

    int lca(int u, int v) {
        for(int tu = top[u], tv = top[v]; tu != tv; u = pat[tu], tu = top[u]) {
            if(dep[tu] < dep[tv])
                swap(u, v), swap(tu, tv);
        }
        return (dep[u] <= dep[v]) ? u : v;
    }
posted @ 2020-12-16 01:19  purinliang  阅读(84)  评论(0编辑  收藏  举报