HDU 2222 Keywords Search(AC自动机模板题)

#include <stdio.h>
#include
<string.h>
#include
<queue>
using namespace std;
const int MAXN = 250010;
const int K = 26;

struct Trie{
int wordEnd;
int fail;
int next[K];
void init(){
wordEnd
= 0;
fail
= -1;
memset(next,
0, sizeof(next));
}
}tree[MAXN];
int cnt;
char str[1000010];

void preProcess(){
cnt
= 0;
tree[
0].init();
}
void inline insert(char *str){
int idx = 0;
while( *str ){
int i = *str - 'a';
if( !tree[idx].next[i] ){
tree[
++cnt].init();
tree[idx].next[i]
= cnt;
}
idx
= tree[idx].next[i];
str
++;
}
tree[idx].wordEnd
++;
}
void BFS(){
queue
<int> que;
int fail, fa, idx;
que.push(
0); //根节点进队
//front = rear = 0;
//que[rear++] = 0;
while( !que.empty() ){
fa
= que.front();
que.pop();
//fa = que[front++];
for(int i = 0; i < K; ++i){
if( tree[fa].next[i] ){
fail
= tree[fa].fail;
idx
= tree[fa].next[i];
que.push(idx);
//所有节点进队一次
//que[rear++] = idx;
while(fail != -1 && tree[fail].next[i] == 0){
fail
= tree[fail].fail;
}
if(fail == -1)
tree[idx].fail
= 0;
else
tree[idx].fail
= tree[fail].next[i];
}
}
}
}
void AC(char *str){
int ans = 0, i, idx = 0, fail;
while( *str ){
i
= *str - 'a';
if( tree[idx].next[i] ) { //相同
idx = tree[idx].next[i];
}
else {
fail
= tree[idx].fail; //指向失败指针
while(fail != -1 && tree[fail].next[i] == 0){
fail
= tree[fail].fail;
}
if(fail == -1){ //一直到根节点 都失配
idx = 0; //
} else { //tree[fail].next[i] != 0
idx = tree[fail].next[i];
}
}
//important
int p = idx;
while ( p != 0 && tree[p].wordEnd ){
if( tree[p].wordEnd ){
ans
+= tree[p].wordEnd;
tree[p].wordEnd
= 0;
}
p
= tree[p].fail;
}
str
++;
}
printf(
"%d\n",ans);
}
int main(){
int t, n;
scanf(
"%d",&t);
while( t-- ){
preProcess();
scanf(
"%d",&n);
while( n-- ){
scanf(
"%s",str);
insert(str);
}
BFS();
scanf(
"%s",str);
AC(str);
}
return 0;
}
posted @ 2011-04-07 16:46  L..  阅读(229)  评论(0编辑  收藏  举报