HDU 2222 AC自动机模版
弄个模版也能花一天。。。。太佩服我自己了。。。。root的初始化都没弄好。。
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> #define val 10005 using namespace std; struct Dictree { int cnt; Dictree *fail,*next[26]; }*root; queue<Dictree*> q; int n,ans; char str[val*100],s[val*100]; void build_tree(); void insert(char *,int); void set_fail(); void ac_auto(char *); void empty_tree(Dictree *); int main() { int t; for(scanf("%d",&t);t;t--) { scanf("%d",&n); getchar(); build_tree(); set_fail(); gets(str); ans=0; ac_auto(str); printf("%d\n",ans); empty_tree(root); } return 0; } void build_tree() { int i; root=(Dictree*)malloc(sizeof(Dictree)); root->cnt=0; memset(root->next,NULL,sizeof(root->next)); for(i=0;i<n;i++) { gets(s); insert(s,i); } } void insert(char *s,int no) { int i; struct Dictree *p,*t; p=root; for(i=0;s[i];i++) { if(p->next[s[i]-'a']==NULL) { t=(Dictree*)malloc(sizeof(Dictree)); memset(t->next,NULL,sizeof(t->next)); t->cnt=0; t->fail=NULL; p->next[s[i]-'a']=t; } p=p->next[s[i]-'a']; } p->cnt++; } void set_fail() { int i; Dictree *p,*temp; root->fail=NULL; q.push(root); while(!q.empty()) { p=q.front(); q.pop(); for(i=0;i<26;i++) { if(p->next[i]) { if(p==root) p->next[i]->fail=root; else { temp=p->fail;//从父亲的fail开始寻找 while(temp) { if(temp->next[i])//儿子中没有该字母,继续寻找 { p->next[i]->fail=temp->next[i]; break; } temp=temp->fail; } if(!temp) p->next[i]->fail=root; } q.push(p->next[i]); } } } } void ac_auto(char *s) { int i,index; Dictree *p,*temp; p=root; for(i=0;s[i];i++) { index=s[i]-'a'; while(p!=root) { if(p->next[index]) break; p=p->fail; } temp=p=p->next[index]; if(p==NULL) temp=p=root; while(temp)//找到了一个,继续找,但不要移动原来的位置 { if(temp->cnt>=0) { ans+=temp->cnt; temp->cnt=-1; } else break; temp=temp->fail; } } } void empty_tree(Dictree *p) { int i; for(i=0;i<26;i++) if(p->next[i]) empty_tree(p->next[i]); free(p); }