• HUST-1350 Trie


    1350 - Trie

    时间限制:1秒 内存限制:128兆

    104 次提交 35 次通过
    题目描述
    In computer science, a trie, is an ordered tree data structure that is used to store an associative array where the keys are usually strings. Each position in the tree shows what key it is associated with and All the descendants of a node have a common prefix of the string associated with that node, have and only have one more character than its father node. the root of the trie is associated with the empty string. For example, if we put 6 words of “to”, “tea”, “ted”, “ten”, “a”, “inn” to a trie, it will be the form of figure.  In the computer science, a trie is a tree. For a tree, we define the leave node is the node without any descendants and only have an edge connect in. So in this example, the leave node is “to”, “tea”, “ted”, “ten”, “a” and “inn”. And we define the distance between two node is the minimum edge from a node to another node must pass. So the distance between “a” and “te” is 3, “to” and “inn” is 5. Finally, we define the value of a node is the sum of the node to the entire leave node’s distance. And the value of a tree is equal the value of a node which have the minimum value. Now give you a list of words. Put them into a trie, and calculate the value of this trie.
    输入
    The first line is T, indicate there are T cases. For each case, the first line is N, indicate there are N words. Next N lines, each line have a word only include the lower case letters and no two words are the same. (N<=50 and the length of a word less than 10)
    输出
    For each case output a line with the value of the trie.
    样例输入
    2
    6
    a
    to
    tea
    ted
    ten
    inn
    4
    sa
    sb
    sc
    sd
    
    样例输出
    Case #1: 13
    Case #2: 5
    
    
    
    /////////////////////////////////////
    For the second case, if the root has only one child, it’s a special leaf and must be calculate.
    
    提示
    来源
    Hong Zehua, HUST Campus 2009
    /**
        题意:给几个字符串,构成一个字典树,求哪个节点到每个叶子的距离最短的,最短是多少
        做法:先建立一个字典树,然后求公共祖先(求得是所有点到叶子节点的最短的距离)
    **/
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <stdio.h>
    #include <string.h>
    #include <queue>
    using namespace std;
    #define maxn 100010
    int tot = 0 ;
    const int MAXN = 100010;
    const int DEG = 30;
    int num[maxn];
    int tot2 = 0;
    int tot3 = 0;
    int num1[maxn];
    int indegree[maxn];
    int mmap[maxn];
    int mm = 0;
    struct Node
    {
        int x;
        int y;
        int flag;
        Node() {};
        Node(int _x, int _y) {
            x = _x;
            y = _y;
            flag = 0;
        }
    } node[maxn << 1];
    struct Trie
    {
        int next[maxn][30], end[maxn];
        int root;
        int L;
        int newnode() {
            for(int i = 0; i < 26; i++) {
                next[L][i] = -1;
            }
            end[L++] = 0;
            return L - 1;
        }
        void init() {
            L = 0;
            root = newnode();
        }
        void insert(char buf[]) {
            int len = strlen(buf);
            int now = root;
            for(int i = 0; i < len; i++) {
                if(next[now][buf[i] - 'a'] == -1) {
                    next[now][buf[i] - 'a'] = newnode();
                    node[tot].y = next[now][buf[i] - 'a'] + 1;
                    node[tot].x = now + 1;
                    node[tot].flag = 0;
                    tot++;
                }
                now = next[now][buf[i] - 'a'];
            }
            node[tot - 1].flag = 1;
            num[tot2++] = node[tot - 1].y;
            end[now]++;
        }
    };
    Trie ac;
    struct Edge
    {
        int to;
        int next;
    } edge[MAXN * 2];
    int head[MAXN], tot1;
    void addedge(int u, int v)
    {
        edge[tot1].to = v;
        edge[tot1].next = head[u];
        head[u] = tot1++;
    }
    void init()
    {
        tot1 = 0;
        memset(head, -1, sizeof(head));
    }
    int fa[MAXN << 1][DEG];
    int deg[MAXN << 1];
    void bfs(int root)
    {
        queue<int>que;
        deg[root] = 0;
        fa[root][0] = root;
        que.push(root);
        while(!que.empty())
        {
            int tmp = que.front();
            que.pop();
            for(int i = 1; i < DEG; i++) {
                fa[tmp][i] = fa[fa[tmp][i - 1]][i - 1];
            }
            for(int i = head[tmp]; i != -1; i = edge[i].next)
            {   int v = edge[i].to;
                if(v == fa[tmp][0]) {
                    continue;
                }
                deg[v] = deg[tmp] + 1;
                fa[v][0] = tmp;
                que.push(v);
            }
        }
    }
    int LCA(int u, int v)
    {
        if(deg[u] > deg[v]) {
            swap(u, v);
        }
        int hu = deg[u], hv = deg[v];
        int tu = u, tv = v;
        for(int det = hv - hu, i = 0; det; det >>= 1, i++)
            if(det & 1) {
                tv = fa[tv][i];
            }
        if(tu == tv) {
            return tu;
        }
        for(int i = DEG - 1; i >= 0; i--)
        {
            if(fa[tu][i] == fa[tv][i]) {
                continue;
            }
            tu = fa[tu][i];
            tv = fa[tv][i];
        }
        return fa[tu][0];
    }
    bool flag[MAXN];
    char buf[30];
    int main()
    {
        //freopen("in.txt", "r", stdin);
        int Case = 1;
        int T;
        scanf("%d", &T);
        while(T--)
        {
            int n;
            tot = 1;    ///边的数目
            tot2 = 0;   ///叶子节点的数目  如果根节点存在Case 2 中的情况也加进去
            tot3 = 0;   ///不是叶子的节点的节点
            mm = 0;
            memset(node, 0, sizeof(node));
            memset(indegree, 0, sizeof(indegree));
            memset(flag, 0, sizeof(flag));
            scanf("%d", &n);
            ac.init();
            for(int i = 0; i < n; i++)
            {
                scanf("%s", buf);
                ac.insert(buf);
            }
            init();
            int yy = 0;
            for(int i = 1; i < tot; i++)
            {
                addedge(node[i].x, node[i].y);
                addedge(node[i].y, node[i].x);
                indegree[node[i].x] ++;
                indegree[node[i].y] ++;
                yy = max(yy, max(node[i].x, node[i].y));
            }
            for(int i = 1; i < tot; i++) {
                if(indegree[node[i].x] == 1) {
                    mmap[mm++] = node[i].x;
                }
                else {
                    num1[tot3++] = node[i].x;
                }
                if(indegree[node[i].y] == 1) {
                    mmap[mm++] = node[i].y;
                }
                else {
                    num1[tot3++] = node[i].y;
                }
            }
            sort(mmap, mmap + mm);
            sort(num1, num1 + tot3);
            int newmm = unique(mmap, mmap + mm) - mmap;
            int newtot3 = unique(num1, num1 + tot3) - num1;
            bfs(1);
            int mmin = 0xfffffff;
            for(int i = 1; i <= yy; i++)
            {
                int temp = 0;
                for(int j = 0; j < newmm; j++)
                {
                    if(i != mmap[j]) {
                        int tt = LCA(i, mmap[j]);
                        int res = 0;
                        res = abs(deg[i] - deg[tt]) + abs(deg[mmap[j]] - deg[tt]);
                        temp += res;
                    }
                }
                mmin = min(mmin, temp);
            }
            printf("Case #%d: %d
    ", Case++, mmin);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    postgresql 高可用 etcd + patroni 之四 failover
    mysql 高可用架构 mha 之三 master_ip_online_change
    postgresql 一种比较个性的 sql 写法
    mysql 高可用架构 mha 之二 master_ip_failover
    mysql 高可用架构 mha 之一 安装
    vacuum 不释放文件系统空间
    mysql slave 复制冲突的解决
    mysql 8.0 登录报错
    oceanbase的一些网址信息
    cockroachdb的一些网址信息
  • 原文地址:https://www.cnblogs.com/chenyang920/p/4786256.html
Copyright © 2020-2023  润新知