• Hdu4547CD操作离线lca


    题意:根目录能一次到达其任意子目录,子目录返回上一层目录需要一次,给出目录关系,问从某个目录到某个目录最少要多少步。

    操作数 ,就是起点到最近公共祖先的距离。

    然后讨论下,如果最近公共祖先等于终点,那么答案就是起点到祖先的高度差 ,否则就是高度差加一 。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<map>
    #include<vector>
    #include<string>
    using namespace std;
    
    const int maxn = 111111;
    
    int father[maxn];
    
    map<pair<int, int>, int> ans;
    vector<int> q[maxn];
    int getfather(int x)
    {
        if (father[x] != x) return father[x] = getfather(father[x]);
        return father[x];
    }
    int len, head[maxn];
    int l[maxn], r[maxn];
    struct Node
    {
        int to; int next;
    }e[maxn * 2];
    int deep[maxn];
    int color[maxn];
    void add(int from, int to)
    {
        e[len].to = to;
        e[len].next = head[from];
        head[from] = len++;
    }
    
    int un(int x, int y)
    {
        int fx = getfather(x); int fy = getfather(y);
        father[fy] = fx;
    }
    
    void dfs(int x)
    {
        for (int i = head[x]; i != -1; i = e[i].next){
            int cc = e[i].to;
            dfs(cc);
            un(x, cc);
        }
        color[x] = 1;
        for (int i = 0; i < q[x].size(); i++){
            int t = q[x][i];
            if (color[t]){
                int gg = getfather(t);
                ans[make_pair(x, t)] = gg;
                ans[make_pair(t, x)] = gg;
            }
        }
    }
    
    void build(int root, int dep)
    {
        deep[root] = dep;
        for (int i = head[root]; i != -1; i = e[i].next){
            int cc = e[i].to;
            build(cc, dep + 1);
        }
    }
    int gg[maxn];
    void init(int n)
    {
        len = 0;
        memset(head, -1, sizeof(head));
        memset(color, 0, sizeof(color));
        memset(gg, 0, sizeof(gg));
        for (int i = 1; i <= n; i++)
            father[i] = i;
        for (int i = 1; i <= n; i++)
            q[i].clear();
    
    }
    
    int main()
    {
        int T;
        int n, M;
        char a[100], b[100];
        cin >> T;
        map<string, int> m;
        while (T--){
            int cnt = 1;
            m.clear();
            scanf("%d%d", &n, &M);
            init(n);
            for (int i = 0; i < n - 1; i++){
                scanf("%s%s", a, b); int c; int d;
                if (!m[a]) m[a] = cnt++;
                if (!m[b]) m[b] = cnt++;
                c = m[a]; d = m[b];
                add(d, c); gg[c] = 1;
            }
            int root;
            for (int i = 1; i <= n; i++)
            if (!gg[i]){
                root = i; break;
            }
            build(root, 1);
            for (int i = 0; i < M; i++){
                scanf("%s%s", a, b);
                int c = m[a]; int d = m[b];
                l[i] = c; r[i] = d;
                q[c].push_back(d);
                q[d].push_back(c);
            }
            dfs(root);
            for (int i = 0; i < M; i++){
                int t = ans[make_pair(l[i], r[i])];
                if (t == r[i]){
                    printf("%d
    ", deep[l[i]] - deep[t]);
                }
                else{
                    printf("%d
    ", deep[l[i]] - deep[t] + 1);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    关于用户体验的几张图片
    上下翻滚JS特效代码
    关注程序员健康之——缺失营养时的六种信号
    C#基础知识系列之——for循环
    关于程序中的需求的变化,责任的分配
    Silverlight学习之——Canvas对象
    还是觉得应该动手写点东西....
    怎样理解“道不同,不相为谋”这句话呢。。。
    UML图中最基本的是类图
    .NET中各种数据库连接大全
  • 原文地址:https://www.cnblogs.com/yigexigua/p/4083540.html
Copyright © 2020-2023  润新知