3 aaa bbb ccc 2 aaabbbccc bbaacc
web 1: 1 2 3 total: 1
//218MS 30636K #include<stdio.h> #include<string.h> #include<vector> using namespace std; char str[10007]; int ans[1007]; int head,tail; struct node { node *next[130];//Trie每个节点的26个字节点 node *fail;//失效指针 int count,id;//是否为该单词的最后一个节点 node()//构造函数初始化 { count=0; fail=NULL; memset(next,0,sizeof(next)); } } *q[500001];//队列,方便用于bfs构造失效指针 void insert(node *root,char str[],int id) { node *p=root; int i=0,index; while(str[i]) { index=str[i]-33; if(p->next[index]==NULL)p->next[index]=new node(); p=p->next[index]; i++; } p->count++;//在单词的最后一个节点count+1,代表一个单词 p->id=id; } void build_ac(node *root) { root->fail=NULL; q[head++]=root; while(head!=tail) { node *temp=q[tail++]; node *p=NULL; for(int i=0; i<129; 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,index; node *p=root; int cnt=0; while(str[i]) { index=str[i]-33;//减的数要比33小 while(p->next[index]==NULL&&p!=root)p=p->fail; p=p->next[index]; p=(p==NULL)?root:p; node *temp=p; while(temp!=root&&temp->count>0)//如果存在 { ans[temp->id]++; cnt++; temp=temp->fail; } i++; } return cnt;//返回匹配的个数 } int main() { int n; while(scanf("%d",&n)!=EOF) { head=tail=0; node *root=new node(); for(int i=0; i<n; i++) { scanf("%s",str); insert(root,str,i+1); } build_ac(root); int m; scanf("%d",&m); int maxx=0; int cas=1; while(m--) { memset(str,0,sizeof(str)); scanf("%s",str); memset(ans,0,sizeof(ans)); int count=query(root); if(count) { printf("web %d:",cas); for(int i=1; i<=n; i++) if(ans[i]>0)printf(" %d",i); printf("\n"); maxx++; } cas++;//带病毒的网站数 } printf("total: %d\n",maxx); } return 0; }
HDU 2896 病毒侵袭 ac自动机(简单),布布扣,bubuko.com
原文:http://blog.csdn.net/crescent__moon/article/details/22755275