首页 > 代码库 > HDU 2222 Keywords Search(AC自动机)
HDU 2222 Keywords Search(AC自动机)
请不要随便指点别人该怎么做、每个人的人生都应该自己掌握、你给不了别人一切、你也不懂别人的忧伤、
微笑不代表快乐、哭泣不一定悲伤
不努力怎么让关心你的人幸福、不努力怎么让看不起你的人绝望、
我用生命在奋斗——lx_Zz
—————————————————————————————————————————————————————————————
————————————————————————— 华丽的分割线 ————————————————————————————
—————————————————————————————————————————————————————————————
AC自动机模板题、注意单词可以重复统计、思路倒是挺简单的、和KMP本质是一样、都是利用已有信息避免重复计算、
/* 题目: HDU 2222 */ /* 作者: lx_Zz */ /* 时间: 2014.5.6 */ #include<cstdio> #include<queue> #include<vector> #include<map> #include<string> #include<iostream> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define INF 0x7fffffff #define LL __int64 const int maxn=500005; int head,tail; char str[1000005]; struct node { node *fail;//失败指针 node *next[26];//每个节点的子节点 int count;//是否为该单词的最后一个节点 node()//构造函数初始化 { fail=NULL; count=0; memset(next,NULL,sizeof(next)); } }*q[maxn]; void insert(node *root)//构建trie树 { node *p=root; int i=0,index; while(str[i]) { index=str[i]-‘a‘; if(p->next[index]==NULL)p->next[index]=new node(); p=p->next[index]; i++; } p->count++; } void ACAutomaton(node *root)//构造AC自动机 { root->fail=NULL; q[head++]=root; while(head!=tail)//bfs遍历出fail指针 { node *temp=q[tail++]; node *p=NULL; for(int i=0;i<26;i++) { if(temp->next[i]!=NULL) { if(temp==root)temp->next[i]->fail=root; else { p=temp->fail; while(p!=NULL) { if(p->next[i]!=NULL) { temp->next[i]->fail=p->next[i]; break; } p=p->fail; } if(p==NULL)temp->next[i]->fail=root; } q[head++]=temp->next[i]; } } } } int query(node *root) { int i=0,cnt=0,index; node *p=root; while(str[i]) { index=str[i]-‘a‘; while(p->next[index]==NULL&&p!=root)p=p->fail;//如果不匹配、跳转到fail指针 p=p->next[index]; if(p==NULL) { p=root; } node *temp=p; while(temp!=root&&temp->count!=0) { cnt+=temp->count; temp->count=0; temp=temp->fail; } i++; } return cnt; } int main() { //freopen("C:\\Users\\终将我要华丽的逆袭\\Desktop\\lx_Zz_in.txt","r",stdin); //freopen("C:\\Users\\终将我要华丽的逆袭\\Desktop\\lx_Zz_out.txt","w",stdout); int T,n; scanf("%d",&T); while(T--) { head=tail=0; node *root=new node(); scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%s",str); insert(root); } ACAutomaton(root); scanf("%s",str); printf("%d\n",query(root)); } return 0; }