zoukankan      html  css  js  c++  java
  • hiho16动态lca

    这个要好写点,就是dfs这棵树,将每个节点进入 和出去的位置都记录下来,

    然后找 所要求得两个点最后出现的位置之间的最小值 所对应的点,就是他们的最近公共祖先。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<map>
    #include<vector>
    using namespace std;
    const int maxn = 111111;
    
    struct edge
    {
        int to; int next;
    }e[maxn*10];
    int len;
    int head[maxn];
    struct Node
    {
        int val; int id;
    }vis[maxn],dp[maxn][20];
    int pos[maxn];
    int cnt;
    void add(int from, int to)
    {
        e[len].to = to;
        e[len].next = head[from];
        head[from] = len++;
    }
    
    void dfs(int x, int val)
    {
        vis[cnt].val = val; vis[cnt].id = x; pos[x] = cnt++;
        for (int i = head[x]; i != -1; i = e[i].next){
            int cc = e[i].to;
            dfs(cc, val + 1);
            vis[cnt].val = val; vis[cnt].id = x; pos[x] = cnt++;
        }
    }
    
    void init(int k)
    {
        for (int i = 0; i < k; i++)
            dp[i][0] = vis[i];
        for (int j = 1; (1 << j) <= k; j++){
            for (int i = 0; i + (1 << j) - 1 < k; i++){
                if (dp[i][j - 1].val < dp[i + (1 << (j - 1))][j - 1].val)
                    dp[i][j] = dp[i][j - 1];
                else dp[i][j] = dp[i + (1 << (j - 1))][j - 1];
            }
        }
    }
    
    int ask(int l, int r)
    {
        int k = 0;
        while ((1 << (k + 1)) < r - l + 1) k++;
        if (dp[l][k].val < dp[r - (1 << k) + 1][k].val) return dp[l][k].id;
        else return dp[r - (1 << k) + 1][k].id;
    }
    int main()
    {
        map<string, int> m;
        map<int, string> m1;
        string a, b;
        int n;
        cin >> n;
        int sum = 1;
        len = 0;
        cnt = 0;
        memset(head, -1, sizeof(head));
        for (int i = 0; i < n; i++){
            cin >> a >> b;
            if (!m.count(a)) m[a] = sum, m1[sum] = a, sum++;
            if (!m.count(b)) m[b] = sum, m1[sum] = b, sum++;
            int  c = m[a]; int d = m[b];
            add(c, d);
        }
        dfs(1, 1);
        init(cnt);
        int q;
        cin >> q;
        while (q--){
            cin >> a >> b; int c = pos[m[a]]; int d = pos[m[b]];
            if (c > d) swap(c, d);
            cout << m1[ask(c, d)] << endl;
        }
        return 0;
    }
  • 相关阅读:
    Tomcat配置JNDI
    (转)通过反编译深入理解Java String及intern
    (转)Java8内存模型-永久代(PermGen)和元空间(Metaspace)
    排序算法
    并发编程
    MySQL
    Go语言
    Go语言
    Go语言
    Go语言
  • 原文地址:https://www.cnblogs.com/yigexigua/p/4072678.html
Copyright © 2011-2022 走看看