UVa 11732 strcmp()函数(左孩子右兄弟表示法)

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<string>
 4 #include<cstring>
 5 #include<vector>
 6 using namespace std;
 7
 8 const int maxn = 4000 * 1000 + 10;
 9 int n;
10 long long ans;
11
12 struct Trie
13 {
14     int head[maxn];     //head[i]为第i个结点的左儿子编号
15     int next[maxn];     //next[i]为第i个结点的右兄弟编号
16     char ch[maxn];      //第i个结点上的字符
17     int tot[maxn];
18     int sz;
19
20     void init()
21     {
22         sz = 1;
23         head[0] = tot[0] = next[0] = 0;
24     }
25
26     void insert(char *s)
27     {
28         int u = 0, v, n = strlen(s);
29         tot[0]++;
30         for (int i = 0; i <= n; i++)
31         {
32             bool found = false;
33             for (v = head[u]; v != 0; v = next[v])
34             {
35                 if (ch[v] == s[i])
36                 {
37                     found = true;
38                     break;
39                 }
40             }
41             if (!found)
42             {
43                 v = sz++;
44                 tot[v] = 0;
45                 ch[v] = s[i];
46                 next[v] = head[u];
47                 head[u] = v;
48                 head[v] = 0;
49             }
50             u = v;
51             tot[u]++;
52         }
53     }
54
55     void dfs(int depth, int u)
56     {
57         if (head[u] == 0)
58             ans += tot[u] * (tot[u] - 1)*depth;
59         else
60         {
61             int sum = 0;
62             for (int v = head[u]; v != 0; v = next[v])
63                 sum += tot[v] * (tot[u] - tot[v]);
64             ans += sum / 2 * (2 * depth + 1);
65             for (int v = head[u]; v != 0; v = next[v])
66                 dfs(depth + 1, v);
67         }
68     }
69 }t;
70
71 int main()
72 {
73     //freopen("D:\\txt.txt", "r", stdin);
74     char str[1005];
75     int kase = 0;
76     while (~scanf("%d", &n), n)
77     {
78         t.init();
79         while (n--)
80         {
81             scanf("%s", str);
82             t.insert(str);
83         }
84         ans = 0;
85         t.dfs(0,0);
86         printf("Case %d: %lld\n", ++kase, ans);
87     }
88     return 0;
89 }
时间: 2024-09-29 17:47:13

UVa 11732 strcmp()函数(左孩子右兄弟表示法)的相关文章

任意有根树的左孩子右兄弟表示法存储

算法导论:10.4-4 对一个含n个结点的任意有根树,写出一个O(n)时间的过程,输出其所有关键字. 该树以左孩子或兄弟表示法存储. #ifndef _ROOTED_TREE_H_ #define _ROOTED_TREE_H_ /***************************************************************** 算法导论:10.4-4 对一个含n个结点的任意有根树,写出一个O(n)时间的过程,输出其所有关键字. 该树以左孩子或兄弟表示法存储. *

左儿子右兄弟表示法

顾名思义 每个节点一个为儿子指针,一个为兄弟指针(在加个父亲) 这样就避免了儿子个数不均带来的问题 TOJ TOJ4077 用一个指针记录当前在哪个节点,需要注意的是可以有多个重名的文件,但是不能在一个目录下. 所以用文件名和其父亲节点作为一个文件的id(区分其他). #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm

UVA - 11732 &quot;strcmp()&quot; Anyone?左兄弟右儿子trie

input n 2<=n<=4000 s1 s2 ... sn 1<=len(si)<=1000 output 输出用strcmp()两两比较si,sj(i!=j)要比较的次数,结果在long long范围内(相同字符比较两次,不相同字符比较一次,包括'\0') 做法:由于字符集太大,要用左兄弟右儿子的trie保存字符,不用每次都开ch[62]个孩子 1 #include <cstdio> 2 #include <queue> 3 #include <

uva 11732 - strcmp() Anyone?(字典树)

题目链接:uva 11732 - strcmp() Anyone? 题目大意:给定n个串,然后两两之间比较,问说总共要比较多少次. 解题思路:字典树,建立出字典树,然后根据字典树的性质在节点记录有多少个字符串包含该节点.因为节点的个数比较多,所以用左孩子右兄弟的方法建立字典树. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long

UVA 11732 &quot;strcmp()&quot; Anyone? (Trie)

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2832 题意:模拟strcmp()函数,给n个字符串,两两之间进行比较,问需要进行多少次比较? 解析:字符串很多,数据量大,按题意两两比较显然不现实.如果把所有的单词插入到一棵Trie里面会怎么样呢?考虑than和that对应的结点,than和that的前3个字符是一样的,但第4个

左儿子右兄弟Trie UVA 11732 strcmp() Anyone?

UVA 11732 strcmp() Anyone?(左儿子右兄弟Trie) ACM 题目地址: UVA 11732 strcmp() Anyone? 题意: 问strcmp函数的==语句执行了几次. UVA 11732 strcmp() Anyone?(左儿子右兄弟Trie) ACM 题目地址: UVA 11732 strcmp() Anyone? 题意: 问strcmp函数的==语句执行了几次. 分析: 大白上的题目. 听说要用左儿子右兄弟的Trie,比较省空间,顺便学了下. 一边inser

UVA 11732 strcmp() Anyone?(左儿子右兄弟Trie)

UVA 11732 strcmp() Anyone?(左儿子右兄弟Trie) ACM 题目地址: UVA 11732 strcmp() Anyone? 题意: 问strcmp函数的==语句执行了几次. 分析: 大白上的题目. 听说要用左儿子右兄弟的Trie,比较省空间,顺便学了下. 开始先建树记录次数,然后再遍历统计,结果错了... 后面参考了Shoutmon巨巨的写法,一边insert一边统计. 代码: /* * Author: illuz <iilluzen[at]gmail.com> *

UVa 11732 &quot;strcmp()&quot; Anyone? (左儿子右兄弟前缀树Trie)

题意:给定strcmp函数,输入n个字符串,让你用给定的strcmp函数判断字符比较了多少次. 析:题意不理解的可以阅读原题https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2832 字符串很多,又很长,如果按照题目的意思两两比较,肯定会TLE,所以要用前缀树(Trie)来解决,当然只是用简单的前缀树也会TLE的, 我们必须对其进行优化,看了

UVa - 11732 - strcmp() Anyone?

先上题目: strcmp() Anyone? Time Limit:2000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Description J ?strcmp()? Anyone? Input: Standard Input Output: Standard Output strcmp() is a library function in C/C++ which compares two stri