字典树(trie)模板

来源:互联网 发布:软件稳定性测试方法 编辑:程序博客网 时间:2024/04/30 13:57

1356: 字典树 密码

时间限制: 1 Sec  内存限制: 128 MB
提交: 43  解决: 29
[提交][状态]

题目描述

现在使用一种新型的密码系统。每一个密码都是一个给定的仅包含小写字母的英文单词表,每个单词至少包含1个字母,至多75个字母。如果在一个由一个词或多个词组成的表中,除了最后一个以外,每个单词都被其后的一个单词所包含,即前一个单词是后一个单词的前缀,则称词表为一个词链。例如下面单词组成了一个词链:
i
int
integer
但下面的单词不组成词链:
integer
intern
现在你要做的就是在一个给定的单词表中取出一些词,组成最长的词链,就是包含单词数最多的词链。将它的单词数统计出来,就得到密码了。

输入

第一行为单词表中的单词数N1<=N<=2000),下面每一行有一个单词,按字典顺序排列,中间也没有重复的单词

输出

一行输出密码

样例输入

5iintintegerinterninternet

样例输出

4
 
字典树,其实就是除根节点外,每个节点包含26个字母的树。
当输入一个单词时,从根节点开始往下找字母。如果已经有了这个字母,就把它的s(到这里构成的单词的数目)++。
如果没有这个字母,就要新创建一个节点。
看起来好像很简单的样子>-<下面是代码及注释
#include<iostream>#include<cmath>#include<cstdio>#include<algorithm>#include<cstring>#include<cstdlib>#include<ctime>using namespace std;struct node {     int s; //到此为止构成的单词,它的数目     int link[27]; //儿子(存字母的) }t[10000]; int ans; int nt; //节点编号 int n; void add(char a[]) {     int ansm=0;     int p=0;     for(int i=0;a[i];i++)     {         int zz=a[i]-'a'+1; //单词的字母         if(t[p].link[zz]==0)//没有这个字母         t[p].link[zz]=++nt;//link[i](i from 1 to 26)<=>字母“i”的结点下标              p=t[p].link[zz];  //走一步         ansm+=t[p].s; //每走一步,统计单词数     }     if(ansm>=ans)ans=ansm+1;     t[p].s++; //这个单词的最后一个字母对应下标的s++ } int main() { char z[100]="";     cin>>n;     for(int i=1;i<=n;i++)     {        cin>>z;         add(z);     }     cout<<ans<<endl;return 0; }

 
 
0 0