http://acm.hdu.edu.cn/showproblem.php?pid=2896
3 aaa bbb ccc 2 aaabbbccc bbaacc
web 1: 1 2 3 total: 1
/** hdu2896 AC自动机-标记哪些模式串在目标串中出现过 题目大意:给定一些模式串,和一些目标串,找出在每一个目标串中有哪些模式串出现过,和总共出现模式串的目标串的个数 解题思路:AC自动机模板题,只需要对每一模式串标记一下就可以了 */ #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <queue> using namespace std; struct Trie { int next[210*500][128],fail[210*500],end[210*500]; int root,L; int newnode() { for(int i=0;i<128;i++) { next[L][i]=-1; } end[L++]=-1; return L-1; } void init() { L=0; root=newnode(); } void insert(char *s,int id) { int len=strlen(s); int now=root; for(int i=0;i<len;i++) { if(next[now][s[i]]==-1) next[now][s[i]]=newnode(); now=next[now][s[i]]; } end[now]=id; } void build() { queue<int>Q; fail[root]=root; for(int i=0;i<128;i++) { if(next[root][i]==-1) next[root][i]=root; else { fail[next[root][i]]=root; Q.push(next[root][i]); } } while(!Q.empty()) { int now=Q.front(); Q.pop(); for(int i=0;i<128;i++) { if(next[now][i]==-1) next[now][i]=next[fail[now]][i]; else { fail[next[now][i]]=next[fail[now]][i]; Q.push(next[now][i]); } } } } bool used[510]; bool query(char *buf,int n,int id) { int len=strlen(buf); int now=root; memset(used,false,sizeof(used)); bool flag=false; for(int i=0;i<len;i++) { now=next[now][buf[i]]; int temp=now; while(temp!=root) { if(end[temp]!=-1) { used[end[temp]]=true; flag=true; } temp=fail[temp]; } } if(!flag)return false; printf("web %d:",id); for(int i=1;i<=n;i++) { if(used[i]) printf(" %d",i); } printf("\n"); return true; } }ac; char buf[10010]; int main() { int m,n; while(scanf("%d",&n)!=EOF) { ac.init(); for(int i=1;i<=n;i++) { scanf("%s",buf); ac.insert(buf,i); } ac.build(); int ans=0; scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%s",buf); if(ac.query(buf,n,i)) ans++; } printf("total: %d\n",ans); } return 0; }