2971: 魔族密码 (trie树)

2971: 魔族密码 分享至QQ空间

时间限制(普通/Java):1000MS/3000MS     内存限制:65536KByte
总提交: 229            测试通过:66

描述

魔族现在使用一种新型的密码系统。每一个密码都是一个给定的仅包含小写字母的英文单词表,每个单词至少包含1个字母,至多75个字母。
如果在一个由一个词或多个词组成的表中,除了最后一个以外,每个单词都被其后的一个单词所包含,即前一个单词是后一个单词的前缀,则称词表为一个词链。
例如下面单词组成了一个词链:
i
int
integer
但下面的单词不组成词链:
integer
intern
现在你要做的就是在一个给定的单词表中取出一些词,组成最长的词链(包含单词数最多的词链)。将它的单词数统计出来,就得到密码了。这些文件的格式是,第一行是单词表中的单词数N(1<=N<=2000),下面每一行有一个单词,按字典顺序排列,中间也没有重复的单词!要提交的文件中只要在第一行输出密码就行啦。

输入

第一行包含一个整数T,表示有T组数据。
对于每组数据,第一行包含一个整数N,表示有N个单词。
以下N行每行有1个字符串,为一个单词。

输出

 

最长的词链的长度。

样例输入

 

样例输出

 

题目来源

TZOJ

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 int tot;
 5 int t,n;
 6 int trie[400005][27];
 7 int money[400005];
 8 string name;
 9 
10 void input(){
11     int len=name.size();
12     int root=0;
13     for(int i=0;i<len;i++){
14         int shu=name[i]-'a';
15         if(!trie[root][shu]) trie[root][shu]=++tot;
16         root=trie[root][shu];
17     }
18     money[root]++;
19 }
20 
21 int maxx;
22 
23 void dfs(int ee,int res){
24 //    cout << ee << " " << money[ee] << endl;
25     res+=money[ee];
26     maxx=max(maxx,res);
27     for(int i=0;i<26;i++){
28         if(trie[ee][i]) dfs(trie[ee][i],res);
29     }
30 }
31 
32 int main(){
33     ios::sync_with_stdio(false);
34     cin>>t;
35     while(t--){
36         tot=0;
37         maxx=0;
38         memset(trie,0,sizeof(trie));
39         memset(money,0,sizeof(money));
40         cin>>n;
41         for(int i=1;i<=n;i++){
42             cin>>name;
43             input();
44         }
45         dfs(0,0);
46         cout << maxx << endl;
47     }
48     return 0;
49 }
View Code
原文地址:https://www.cnblogs.com/qq-1585047819/p/11320864.html