hdu2896病毒侵袭(ac自动机)

链接

ac自动机的模板题

说2个注意的地方 一是题目说明包含所有ASCII字符,可以开到0-127 包含空格

题目会输入多个源串,在加完当前的val值时,不应清0,可以开个标记数组。

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 100010
 12 #define M 510
 13 #define LL long long
 14 #define INF 0xfffffff
 15 const double eps = 1e-8;
 16 const double pi = acos(-1.0);
 17 const double inf = ~0u>>2;
 18 const int child_num = 128;
 19 int g;
 20 int o[M];
 21 char s[N];
 22 bool f[M];
 23 class ACAutomo
 24 {
 25     private:
 26     int ch[N][child_num];
 27     int val[N];
 28     int fail[N];
 29     int Q[N];
 30     int id[128];
 31     int sz;
 32     public:
 33     void init()
 34     {
 35         fail[0] = 0;
 36         for(int i = 0; i < child_num ; i++)
 37         id[i] = i;
 38     }
 39     void reset()
 40     {
 41         memset(ch[0],0,sizeof(ch[0]));
 42         sz = 1;
 43     }
 44     void insert(char *a,int key)
 45     {
 46         int p = 0 ;
 47         for( ; *a ; a++)
 48         {
 49             int d = id[*a];
 50             if(ch[p][d]==0)
 51             {
 52                 memset(ch[sz],0,sizeof(ch[sz]));
 53                 val[p] = 0;
 54                 ch[p][d] = sz++;
 55             }
 56             p = ch[p][d];
 57         }
 58         val[p]=key;
 59     }
 60     void construct()
 61     {
 62         int i,head=0,tail = 0;
 63         for(i = 0 ;i < child_num ; i++)
 64         {
 65             if(ch[0][i])
 66             {
 67                 Q[tail++] = ch[0][i];
 68                 fail[ch[0][i]] = 0;
 69             }
 70         }
 71         while(head!=tail)
 72         {
 73             int u = Q[head++];
 74             for(i = 0; i < child_num ; i++)
 75             {
 76                 if(ch[u][i])
 77                 {
 78                     Q[tail++] = ch[u][i];
 79                     fail[ch[u][i]] = ch[fail[u]][i];
 80                 }
 81                 else
 82                 ch[u][i] = ch[fail[u]][i];
 83             }
 84         }
 85     }
 86     void work(char *s)
 87     {
 88         int i,k = strlen(s);
 89         memset(f,0,sizeof(f));
 90         int p = 0;
 91         for(i = 0 ;i < k ; i++)
 92         {
 93             int d = id[s[i]];
 94             p = ch[p][d];
 95             int tmp = p;
 96             while(tmp!=0&&(val[tmp]!=0||f[val[tmp]]))
 97             {
 98                 if(!f[val[tmp]])
 99                 o[g++] = val[tmp];
100                 f[val[tmp]] = 1;
101                 tmp = fail[tmp];
102             }
103         }
104     }
105 }ac;
106 int main()
107 {
108     int n,m,i;
109     char vir[210];
110     ac.init();
111     while(scanf("%d%*c",&n)!=EOF)
112     {
113         ac.reset();
114         for(i = 1; i <= n; i++)
115         {
116             gets(vir);
117             ac.insert(vir,i);
118         }
119         scanf("%d%*c",&m);
120         int ans = 0;
121         ac.construct();
122         for(i = 1; i <= m ;i++)
123         {
124             gets(s); g = 0 ;
125             ac.work(s);
126             if(g==0) continue;
127             printf("web %d:",i);
128             sort(o,o+g);
129             for(int j = 0 ;j < g ; j++)
130             printf(" %d",o[j]);
131             puts("");
132             ans++;
133         }
134         printf("total: %d\n",ans);
135     }
136     return 0;
137 }
View Code

 

posted @ 2014-05-14 15:25  _雨  阅读(160)  评论(0编辑  收藏  举报