zoukankan      html  css  js  c++  java
  • 洛谷 P3379 【模板】最近公共祖先(LCA)

    传送门

    Version 1: 倍增

    #include <bits/stdc++.h>
    
    using namespace std;
    using ll = long long;
    using p = pair<int, int>;
    const int maxn(5e5 + 10);
    const int maxm(1e6 + 10);
    int ecnt, head[maxn];
    int dep[maxn], f[maxn][20];
    
    struct edge {
        int to, nxt;
    } edges[maxm];
    
    template<typename T = int>
    inline const T read()
    {
        T x = 0, f = 1;
        char ch = getchar();
        while (ch < '0' || ch > '9') {
            if (ch == '-') f = -1;
            ch = getchar();
        }
        while (ch >= '0' && ch <= '9') {
            x = (x << 3) + (x << 1) + ch - '0';
            ch = getchar();
        }
        return x * f;
    }
    
    template<typename T>
    inline void write(T x, bool ln)
    {
        if (x < 0) {
            putchar('-');
            x = -x;
        }
        if (x > 9) write(x / 10, false);
        putchar(x % 10 + '0');
        if (ln) putchar(10);
    }
    
    void addEdge(int u, int v)
    {
        edges[ecnt].to = v;
        edges[ecnt].nxt = head[u];
        head[u] = ecnt++;
    }
    
    void bfs(int root)
    {
        queue<int> q;
        q.push(root);
        dep[root] = 1;
        while (not q.empty()) {
            int u = q.front();
            q.pop();
            for (int i = head[u]; compl i; i = edges[i].nxt) {
                int v = edges[i].to;
                if (dep[v]) {
                    continue;
                }
                q.push(v);
                dep[v] = dep[u] + 1;
                f[v][0] = u;
                for (int j = 1; j < 20; ++j) {
                    f[v][j] = f[f[v][j - 1]][j - 1];
                }
            }
        }
    }
    
    int lca(int u, int v)
    {
        if (dep[u] < dep[v]) {
            swap(u, v);
        }
        for (int i = 19; i >= 0; --i) {
            if (dep[f[u][i]] >= dep[v]) {
                u = f[u][i];
            }
        }
        if (u == v) {
            return u;
        }
        for (int i = 19; i >= 0; --i) {
            if (f[u][i] not_eq f[v][i]) {
                u = f[u][i];
                v = f[v][i];
            }
        }
        return f[u][0];
    }
    
    int main()
    {
    #ifdef ONLINE_JUDGE
    #else
        freopen("input.txt", "r", stdin);
    #endif
        ios::sync_with_stdio(false);
        memset(head, -1, sizeof head);
        int n = read(), m = read(), s = read();
        for (int i = 0; i < n - 1; ++i) {
            int u = read(), v = read();
            addEdge(u, v);
            addEdge(v, u);
        }
        bfs(s);
        while (m--) {
            int u = read(), v = read();
            write(lca(u, v), true);
        }
        return 0;
    }
    

    Version 2: 离线 Tarjan

    #include <bits/stdc++.h>
    
    using namespace std;
    using ll = long long;
    using p = pair<int, int>;
    const int maxn(5e5 + 10);
    const int maxm(1e6 + 10);
    int ecnt, qcnt;
    bool vis[maxn];
    int ehead[maxn], qhead[maxm];
    int pre[maxn], ans[maxm];
    
    struct edge {
        int to, nxt;
    } edges[maxm];
    
    struct que {
        int id, to, nxt;
    } ques[maxm];
    
    template<typename T = int>
    inline const T read()
    {
        T x = 0, f = 1;
        char ch = getchar();
        while (ch < '0' || ch > '9') {
            if (ch == '-') f = -1;
            ch = getchar();
        }
        while (ch >= '0' && ch <= '9') {
            x = (x << 3) + (x << 1) + ch - '0';
            ch = getchar();
        }
        return x * f;
    }
    
    template<typename T>
    inline void write(T x, bool ln)
    {
        if (x < 0) {
            putchar('-');
            x = -x;
        }
        if (x > 9) write(x / 10, false);
        putchar(x % 10 + '0');
        if (ln) putchar(10);
    }
    
    void addEdge(int u, int v)
    {
        edges[ecnt].to = v;
        edges[ecnt].nxt = ehead[u];
        ehead[u] = ecnt++;
    }
    
    void addQue(int id, int u, int v)
    {
        ques[qcnt].id = id;
        ques[qcnt].to = v;
        ques[qcnt].nxt = qhead[u];
        qhead[u] = qcnt++;
    }
    
    int Find(int x)
    {
        return pre[x] == x ? x : pre[x] = Find(pre[x]);
    }
    
    void Union(int u, int v)
    {
        pre[Find(v)] = Find(u);
    }
    
    void dfs(int cur, int pre)
    {
        vis[cur] = true;
        for (int i = ehead[cur]; compl i; i = edges[i].nxt) {
            int nxt = edges[i].to;
            if (nxt not_eq pre) {
                dfs(nxt, cur);
            }
        }
        for (int i = qhead[cur]; compl i; i = ques[i].nxt) {
            int id = ques[i].id, nxt = ques[i].to;
            if (vis[nxt]) {
                ans[id] = Find(nxt);
            }
        }
        Union(pre, cur);
    }
    
    void tarjan(int tot, int root)
    {
        for (int i = 1; i <= tot; ++i) {
            pre[i] = i;
        }
        dfs(root, 0);
    }
    
    int main()
    {
    #ifdef ONLINE_JUDGE
    #else
        freopen("input.txt", "r", stdin);
    #endif
        ios::sync_with_stdio(false);
        memset(ehead, -1, sizeof ehead);
        memset(qhead, -1, sizeof qhead);
        int n = read(), m = read(), s = read();
        for (int i = 0; i < n - 1; ++i) {
            int u = read(), v = read();
            addEdge(u, v);
            addEdge(v, u);
        }
        for (int i = 0; i < m; ++i) {
            int u = read(), v = read();
            addQue(i, u, v);
            addQue(i, v, u);
        }
        tarjan(n, s);
        for (int i = 0; i < m; ++i) {
            write(ans[i], true);
        }
        return 0;
    }
    
  • 相关阅读:
    python 包管理工具 pip 的配置
    Python 变量作用域 LEGB (下)—— Enclosing function locals
    Python 变量作用域 LEGB (上)—— Local,Global,Builtin
    2020 Java 面试题 小结 (答案慢慢补上,有错误请指出)
    mysql 根据日期(date)做年,月,日分组统计查询
    jvm指令
    正则表达式 分割地址 获取省市区详细地址
    .Net 异常记录
    WCF设计服务协议(一)
    plsql ORA-01789:查询块具有不正确的结果列数
  • 原文地址:https://www.cnblogs.com/singularity2u/p/13880795.html
Copyright © 2011-2022 走看看