转转:   
 http://hi.baidu.com/ecchi/blog/item/84bcdc3ff832a5c37d1e71bf.html
  Trie树2007-03-12 17:46转自xiaoyao4005.cublog.cnTrie树既可用于一般的字典搜索,也可用于索引查找。对于给定的一个字符串a1,a2,a3,...,an.则采用TRIE树搜索经过n次搜索即可完成一次查找。不过好像还是没有B树的搜索效率高,B树搜索算法复杂度为logt(n+1/2).当t趋向大,搜索效率变得高效。怪不得DB2的访问内存设置为虚拟内存的一个PAGE大小,而且帧切换频率降低,无需经常的PAGE切换。// trie.cpp : 定义控制台应用程序的入口点。

http://acm.pku.edu.cn/JudgeOnline/problem?id=2564

// trie树加动态规划
// 刚开始以为会超时,以为复杂度是o( 25000 * 16 * 26 ) * o( 16 )
// 还没搞明白那trie树的查询时间到底是o( 1 )还是o( 16 )呢?
#include
< stdio.h >
#include
< iostream >
#include
< memory.h >
#include
< string .h >
using namespace std;
#define MAX 
25001
#define M 
26
int  rec,rec2;
char q[M];
char p[M];
int  ans;
class Trie{
public :
    Trie();
    ~Trie();
    
int  insert(char  * key);
    
int  search(char  * key);
    struct Trie_node{
        char 
* p;
        
int  num;
        Trie_node 
* next [M];
        Trie_node();
    };
    Trie_node 
* root;
};
Trie::Trie_node::Trie_node(){
    p
= NULL ;
    
for ( int  i = 0 ;i < M;i ++ ){
        
next [i] = NULL ;
    }
}
Trie::Trie(){
    root
= NULL ;
}
Trie::~Trie(){
}
int  Trie::insert(char  * key){ // 插入,插入成功后返回1
    
int  char_node;
    char 
* g = new  char[strlen(key) + 1 ];
    strcpy(g,key);
    
if (root == NULL ){
        root
= new  Trie_node;
    }
    Trie_node 
* cur = root;
    
while (cur &&* key! = 0 ){
        
if ( * key >= ' a'&&*key<='z'){
            char_node =* key - ' a';
        }
        
else   if ( * key >= ' A'&&*key<='Z'){
                char_node =* key - ' A';
            }
            
else  return  0 ;
        
if (cur -> next [char_node] == NULL ){
            cur
-> next [char_node] = new  Trie_node;
        }
        cur
= cur -> next [char_node];
        key
++ ;
    }
    cur
-> num = rec2;
    cur
-> p = new  char[strlen(g) + 1 ];
    strcpy(cur
-> p,g);
    return 
1 ;
}
int  Trie:: search(char  * key) // 查找,找到后放于entry中,返回1
{
    Trie_node 
* cur = root;
    
int  char_node;
    char k[M];
    strcpy(k,key);
    
while (cur &&* key! = 0 ){
        
if ( * key >= ' a'&&*key<='z'){
            char_node =* key - ' a';
        }
        
else  { if ( * key >= ' A'&&*key<='Z'){
                char_node =* key - ' A';
            }
        
else  {return  0 ;}
        }
        cur
= cur -> next [char_node];
        key
++ ;
    }
    
if (cur! = NULL && cur -> p! = NULL ){
        
if (rec < cur -> num + 1 ){rec = cur -> num + 1 ;}
        return 
1 ;
    }
    return 
0 ;
}
Trie t;
int  Least(){
    
int  i,j,k,q_len;
    char ch,sh;
    q_len
= strlen(q);
    rec
= 1 ;
    
for (i = 0 ;i < q_len;i ++ ){
        
for (k = j = 0 ;j < q_len - 1 ;j ++ ,k ++ ){
            
if (k == i)k ++ ;
            p[j]
= q[k];
        }
        p[j]
= ' \0';
        t.search(p);
    }
    
if (ans < rec)ans = rec;
    rec2
= rec;
    rec
= 1 ;
    
for (i = 0 ;i < q_len;i ++ ){
        ch
= q[i];
        
for (sh = ' a';sh<='z';sh++){
            q[i] = sh;
            t.search(q);
        }
        q[i]
= ch;
    }
    
if (ans < rec)ans = rec;
    
if (rec2 < rec)rec2 = rec;
    rec
= 1 ;
    
for (i = 0 ;i < q_len;i ++ ){
        
for (j = 0 ;j < i;j ++ ){
            p[j]
= q[j];
        }
        
for (j = q_len;j > i;j -- ){
            p[j]
= q[j - 1 ];
        }
        p[q_len
+ 1 ] = ' \0';
         for (sh = ' a';sh<='z';sh++){
            p[i] = sh;
            t.search(p);
        }
    }
    strcpy(p,q);
    p[q_len
+ 1 ] = ' \0';
     for (sh = ' a';sh<='z';sh++){
        p[q_len] = sh;
        t.search(p);
    }
    
if (ans < rec)ans = rec;
    
if (rec2 < rec)rec2 = rec;
    t.insert(q);
    return 
0 ;
}
int  main(){
    
int  i,j,k,g,q_len;
    ans
= 0 ;
    
while (scanf( " %s " ,q)! = EOF){
        Least();
    }
    printf(
" %d\n " ,ans);
    return 
0 ;
}