zoukankan      html  css  js  c++  java
  • BZOJ 4567: [Scoi2016]背单词

    二次联通门 : BZOJ 4567: [Scoi2016]背单词

    /*
        BZOJ 4567: [Scoi2016]背单词
    
        Trie + 贪心
    
        大家都吐槽题目反人类
        可我觉得还好,毕竟见的多了
        
        不会做啊。。
        正解好巧妙
        
        考虑一下,发现一操作完全不必要,可以省去
        因为所有的字符串的后缀关系会形成一个树
    
        那么把字符串倒序插入Trie中
        建树,每次向子树小的一个点转移即可
    */
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #define Max 100008
    #define L 26
    int N;
    char line[Max];
    
    int trie[Max][L], T_C = 1;
    bool is[Max];
    struct E
    {
        E *n; int to;
    };
    E *list[Max], poor[Max], *Ta = poor;
    void Dfs (int now, int Father)
    {
        if (is[now]) 
        {
            ++ Ta, Ta->to = now, Ta->n = list[Father], list[Father] = Ta;
            Father = now;
        }
        for (int i = 0; i < L; ++ i) 
            if (trie[now][i]) 
                Dfs (trie[now][i], Father);
    }
    int size[Max];
    
    void Re_Dfs (int now)
    {
        size[now] = 1;
        for (E *e = list[now]; e; e = e->n)
            Re_Dfs (e->to), size[now] += size[e->to];
    }
    int dfn[Max], top, C, Stack[Max], Answer;
    inline bool Comp (int a, int b)
    {
        return size[a] < size[b];
    }
    void Get_Answer (int now)
    {
        dfn[now] = ++ C; int pos = top + 1;
        for (E *e = list[now]; e; e = e->n)
            Stack[++ top] = e->to;
        if (top < pos) return ;
        std :: sort (Stack + pos, Stack + top + 1, Comp);
        for (int i = pos; i <= top; ++ i)
            Get_Answer (Stack[i]), Answer += dfn[Stack[i]] - dfn[now];
        top = pos - 1;
    }
    
    int Main ()
    {
        scanf ("%d", &N); register int i, j;
        int Id, x, now, Len;
        for (i = 1; i <= N; ++ i)
        {
            scanf ("%s", line); Len = strlen (line);
            for (j = Len - 1, now = 1; j >= 0; -- j)
            {
                Id = line[j] - 'a';
                if (trie[now][Id] == 0)
                    trie[now][Id] = ++ T_C;
                now = trie[now][Id];
            }    
            is[now] = true;
        }    
        Dfs (1, 1), Re_Dfs (1), Get_Answer (1);
        printf ("%d", Answer);
        return 0;
    }
    int ZlycerQan = Main ();
    int main (int argc, char *argv[]) {;}
  • 相关阅读:
    除下草并推荐PhantomJS
    GTAC 2013
    Benchmark感受
    ChinaTest第二天
    "西厂"、"东厂"照片
    谈面试上
    mysql基本常用命令(转)
    java学习笔记数据类型、运算符和控制语句
    java学习笔记第一个applet程序以及一个小问题的解决
    网上阅卷系统自动识别功能代码
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/7429388.html
Copyright © 2011-2022 走看看