HDU 2896 病毒侵袭 (AC自动机)

与HDU2222差不多。。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<string>
 6 #include<algorithm>
 7 #include<queue>
 8 int n,m;
 9 char s[100005];
10 struct Trie{
11       int fail[200005],used[10005],end[200005],next[200005][130],L,root;
12       int newnode(){
13           for (int i=0;i<=128;i++)
14            next[L][i]=-1;
15           end[L++]=-1;
16           return L-1;
17       }    
18       void clear(){
19           L=0;root=newnode();
20       }
21       void insert(char s[],int id){
22           int now=root,len=strlen(s);
23         for (int i=0;i<len;i++){
24             if (next[now][s[i]]==-1) next[now][s[i]]=newnode();
25             now=next[now][s[i]];
26         }
27         end[now]=id;
28       }
29       void build(){
30           std::queue<int> Q;
31           int now=root;
32           for (int i=0;i<=128;i++)
33            if (next[root][i]==-1) next[root][i]=root;
34            else{
35                fail[next[root][i]]=root;
36                Q.push(next[root][i]);
37            }
38           while (!Q.empty()){
39               int now=Q.front();
40               Q.pop();
41               for (int i=0;i<=128;i++){
42                   if (next[now][i]==-1)
43                    next[now][i]=next[fail[now]][i];
44                   else{
45                       fail[next[now][i]]=next[fail[now]][i];
46                       Q.push(next[now][i]);
47                   } 
48               }
49           } 
50       }
51       bool query(char s[],int n,int id){
52            int len=strlen(s);
53            int now=root;
54            memset(used,0,sizeof used);
55            bool flag=false;
56            for (int i=0;i<len;i++){
57                now=next[now][s[i]];
58                int tmp=now;
59                while (tmp!=root){
60                    if (end[tmp]!=-1) used[end[tmp]]=1,flag=true;
61                    tmp=fail[tmp];
62                }
63            }
64            if (!flag) return 0;
65            printf("web %d:",id);
66            for (int i=1;i<=n;i++)
67             if (used[i])
68              printf(" %d",i);
69            printf("\n");
70            return 1;
71       }
72 }ac;
73 int main(){
74     while (scanf("%d",&n)!=EOF){
75     ac.clear();
76     for (int i=1;i<=n;i++){
77         scanf("%s",s);
78         ac.insert(s,i);
79     }
80     ac.build();
81     scanf("%d",&m);
82     int ans=0;
83     for (int i=1;i<=m;i++){
84         scanf("%s",s);
85         if (ac.query(s,n,i)) ans++;
86     }
87     printf("total: %d\n",ans);
88     }
89 }

 

posted @ 2016-06-02 08:09  GFY  阅读(184)  评论(0编辑  收藏  举报