zoukankan      html  css  js  c++  java
  • 【UVA】11732

    一開始不知道这样的一维建树方法。

    每次一层用一个链指向下一层最左边的结点,之后每一层用一个链表串联全部的结点,这样就建树成功了。

    14328524 11732 strcmp() Anyone?

    Accepted C++ 0.826 2014-10-09 13:13:14

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> pill;
    const int nodemaxn = 4000 * 1000 + 100;
    struct Trie{
        int head[nodemaxn]; //左儿子链
        int next[nodemaxn]; //右兄弟链
        int   ch[nodemaxn]; //这个结点代表的字符
        LL   tot[nodemaxn]; //有几个单词经过了这个结点
        int   sz;           //结点个数
        LL   ret;           //比較的次数
        void clear(){
            head[0] = 0; next[0] = 0; tot[0] = 0; sz = 1; ret = 0;
        }
        void insert(char *str){
            int L = strlen(str);
            int u = 0,v,found;
            tot[0]++;
            for(int i = 0; i <= L; i ++){
                found = 0;
                for(v = head[u]; v != 0 ; v = next[v]){  //到下一层去找
                    if(ch[v] == str[i]){
                        found = 1;
                        break;
                    }
                }
                if(!found){  //假设没有找到
                    v = sz ++;
                    tot[v] = 0;
                    ch[v] = str[i];
                    next[v] = head[u];
                    head[u] = v;
                    head[v] = 0;
                }
                u = v;
                tot[u] ++;
            }
        }
        void dfs(int u,int depth){
            if(head[u] == 0){
                ret += tot[u] * (tot[u] - 1) * depth;
            }
            else{
                LL sum = 0;
                for(int v = head[u] ; v != 0; v = next[v])
                    sum += tot[v] * (tot[u] - tot[v]);
                ret += sum / 2 * (2 * depth + 1);
                for(int v = head[u] ; v != 0; v = next[v])
                    dfs(v,depth + 1);
            }
        }
    }trie;
    const int maxn = 4000 + 10;
    int main(){
        int n,Case = 1;
        while(scanf("%d",&n) && n){
            trie.clear();
            for(int i = 0; i < n; i++){
                char str[maxn];
                scanf("%s",str);
                trie.insert(str);
            }
            trie.dfs(0,0);
            printf("Case %d: %lld
    ",Case++,trie.ret);
        }
    }
    

  • 相关阅读:
    最小乘积(基本型)
    删除数组零元素
    大小写转换
    矩阵乘法
    字串统计
    出现次数最多的整数
    Anagrams问题
    前缀表达式
    2的次幂表示
    POJ
  • 原文地址:https://www.cnblogs.com/yxwkf/p/5315250.html
Copyright © 2011-2022 走看看