[hdu2896]病毒侵袭(AC自动机)

题意:给出n个病毒和m个网站,找出每一个网站中含有的病毒种类,并按病毒编号升序输出,最后统计含有病毒的网站个数。

每道AC自动机不同的地方就是end数组代表的意义,这里还需要加一个vis数组判断是否访问过。其他就是ASCII码可见字符为32-196 共95个字符。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N=96;
 5 const int MAXN=100010;
 6 int num,ans[5],nn;
 7 bool vis[MAXN];
 8 struct Trie{//数组形式 
 9     int Next[MAXN][N],Fail[MAXN],End[MAXN],root,tot;//大小为所以匹配字符串的总和 
10     int newnode(){//结构体内部用 
11         for(int i=0;i<N;i++) Next[tot][i]=-1;
12         End[tot++]=0;
13         return tot-1;
14     }
15     void init(){
16         tot=0;
17         root=newnode();
18     }
19     void insert(char buf[],int x){
20         int len=strlen(buf);
21         int now=root;//now是temp指针 
22         for(int i=0;i<len;i++){
23             int k=buf[i]-32;
24             if(Next[now][k]==-1)  Next[now][k]=newnode();//next数组代表的是下一个字符索引 
25             now=Next[now][k];
26         }
27         End[now]=x;//end数组是当前字符串的个数.字典中可能有相同的单词,若只算一次,改为1. 
28     }
29     void build(){//构造fail指针,后缀是某些前缀 
30         queue<int>que;
31         Fail[root]=root;
32         for(int i=0;i<N;i++){ 
33             if(Next[root][i]==-1) Next[root][i]=root;
34             else{
35                 Fail[Next[root][i]]=root;
36                 que.push(Next[root][i]);
37             }
38         } 
39         while(!que.empty()){//bfs,会将所有的匹配子串都遍历到 
40             int now=que.front();
41             que.pop();
42             for(int i=0;i<N;i++){
43                 if(Next[now][i]==-1) Next[now][i]=Next[Fail[now]][i];
44                 else{
45                     Fail[Next[now][i]]=Next[Fail[now]][i];//fail指向最长的 
46                     que.push(Next[now][i]);
47                 }
48             }
49         }
50     }
51     void query(char buf[]){
52         int len=strlen(buf),now=root;
53         for(int i=0;i<len;i++){
54             now=Next[now][buf[i]-32];
55             int temp=now;
56             while(temp!=root){
57                 if(!vis[temp]&&End[temp]) ans[nn++]=End[temp];
58                 vis[temp]=true;
59                 temp=Fail[temp];
60             }
61         }
62     }
63 };
64 
65 Trie ac;
66 char buf[10003];
67 int n,m;
68 int main(){
69     num=0;
70     ios::sync_with_stdio(0);
71     ac.init();
72     cin>>n;
73     for(int i=1;i<=n;i++){
74         cin>>buf;
75         ac.insert(buf,i);
76     }
77     ac.build();//不要忘记build 
78     cin>>m;
79     for(int i=1;i<=m;i++){
80         memset(vis,0,sizeof vis);
81         nn=0;
82         cin>>buf;
83         ac.query(buf);
84         if(nn==0) continue;
85         sort(ans,ans+nn);
86         cout<<"web "<<i<<":";
87         for(int j=0;j<nn;j++){
88             cout<<" "<<ans[j];
89         }
90         cout<<"\n";
91         num++;
92     }
93     cout<<"total: "<<num<<"\n";
94     return 0;
95 } 

 

posted @ 2017-09-11 20:19  Elpsywk  阅读(168)  评论(0编辑  收藏  举报