hdu2896:

题意:有一些串是病毒串(模式串),标号1~n,给出m个待匹配串,问每个模式串中有哪些病毒串,从小到大输出,并求共有多少待匹配串含有病毒串

就是将AC自动机的模板改了一下,用模式串结尾结点记录下这是哪个模式串的结尾,在遍历时再排序输出即可

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<queue>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxm=520*250;
 7 
 8 char s[10020],word[210];
 9 bool vis[maxm];
10 int nxt[maxm][128-30],cnt[maxm],fail[maxm],size;
11 int ans[520],c;
12 
13 int newnode(){
14     memset(nxt[size],0,sizeof(nxt[size]));
15     fail[size]=cnt[size]=0;
16     return size++;
17 }
18 
19 void insert(char s[],int k){
20     int i,p=0;
21     for(i=0;s[i];i++){
22         int &x=nxt[p][s[i]-30];
23         p=x?x:x=newnode();
24     }
25     cnt[p]=k;
26 }
27 
28 void makenxt(){
29     int i;
30     queue<int>q;
31     q.push(0);
32     while(!q.empty()){
33         int u=q.front();
34         q.pop();
35         for(i=0;i<128-30;i++){
36             int v=nxt[u][i];
37             if(v==0)nxt[u][i]=nxt[fail[u]][i];
38             else q.push(v);    
39             if(u&&v){
40                 fail[v]=nxt[fail[u]][i];
41             }
42         }
43     }
44 }
45 
46 bool query(char s[]){
47     int d=0;
48     bool f=0;
49     for(int i=0;s[i];i++){
50         d=nxt[d][s[i]-30];
51         int tmp=d;
52         while(tmp!=0){
53             if(cnt[tmp]&&!vis[tmp]){
54                 f=1;
55                 vis[tmp]=1;
56                 ans[++c]=cnt[tmp];
57             }
58             tmp=fail[tmp];
59         }
60     }
61     return f;
62 }
63 
64 int main(){
65     int n,m,i;
66     while(scanf("%d",&n)!=EOF){
67         memset(cnt,0,sizeof(cnt));
68         size=0,newnode();
69         for(i=1;i<=n;i++){
70             scanf("%s",word);
71             insert(word,i);
72         }
73         makenxt();
74         scanf("%d",&m);
75         int res=0;
76         for(i=1;i<=m;i++){
77             memset(vis,0,sizeof(vis));
78             c=0;
79             scanf("%s",s);
80             if(query(s)){
81                 res++;
82                 sort(ans+1,ans+c+1);
83                 printf("web %d:",i);
84                 for(int j=1;j<=c;j++){
85                     printf(" %d",ans[j]);
86                 }
87                 printf("\n");
88             }
89         }
90         printf("total: %d\n",res);
91     }
92     return 0;
93 }
hdu2896