hdu 2896(AC自动机)

病毒侵袭

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 36709    Accepted Submission(s): 8149


Problem Description
当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻。。。。在这样的时刻,人们却异常兴奋——我们能在有生之年看到500年一遇的世界奇观,那是多么幸福的事儿啊~~
但网路上总有那么些网站,开始借着民众的好奇心,打着介绍日食的旗号,大肆传播病毒。小t不幸成为受害者之一。小t如此生气,他决定要把世界上所有带病毒的网站都找出来。当然,谁都知道这是不可能的。小t却执意要完成这不能的任务,他说:“子子孙孙无穷匮也!”(愚公后继有人了)。
万事开头难,小t收集了好多病毒的特征码,又收集了一批诡异网站的源码,他想知道这些网站中哪些是有病毒的,又是带了怎样的病毒呢?顺便还想知道他到底收集了多少带病毒的网站。这时候他却不知道何从下手了。所以想请大家帮帮忙。小t又是个急性子哦,所以解决问题越快越好哦~~
 
Input
第一行,一个整数N(1<=N<=500),表示病毒特征码的个数。
接下来N行,每行表示一个病毒特征码,特征码字符串长度在20—200之间。
每个病毒都有一个编号,依此为1—N。
不同编号的病毒特征码不会相同。
在这之后一行,有一个整数M(1<=M<=1000),表示网站数。
接下来M行,每行表示一个网站源码,源码字符串长度在7000—10000之间。
每个网站都有一个编号,依此为1—M。
以上字符串中字符都是ASCII码可见字符(不包括回车)。
 
Output
依次按如下格式输出按网站编号从小到大输出,带病毒的网站编号和包含病毒编号,每行一个含毒网站信息。
web 网站编号: 病毒编号 病毒编号 …
冒号后有一个空格,病毒编号按从小到大排列,两个病毒编号之间用一个空格隔开,如果一个网站包含病毒,病毒数不会超过3个。
最后一行输出统计信息,如下格式
total: 带病毒网站数
冒号后有一个空格。
 
Sample Input
3
aaa
bbb
ccc
2
aaabbbccc
bbaacc
 
Sample Output
web 1: 1 2 3
total: 1
 
  1 /**
  2     完成时间:2018.9.12
  3             依言
  4     算法:AC自动机
  5 */
  6 #include<iostream>
  7 #include<queue>
  8 #include<cstdio>
  9 #include<cstring>
 10 #include<algorithm>
 11 using namespace std;
 12 const int SON=128;
 13 const int MAXN=200*500+50;
 14 
 15 struct AC_Auto
 16 {
 17     int root,L;
 18     int next[MAXN][SON];
 19     int fail[MAXN];
 20     int num[4];
 21     int number[MAXN];
 22     int New_Node()
 23     {
 24         for(int i=0;i < SON;++i)
 25             next[L][i]=-1;
 26         num[L]=0;
 27         return L++;
 28     }
 29     void Initial()
 30     {
 31         L=0;
 32         root=New_Node();
 33     }
 34     void Build_Trie(const char *s,const int id)
 35     {
 36         int now=root;
 37         while(*s != '\0')
 38         {
 39             int index=*s;
 40             if(next[now][index] == -1)
 41                 next[now][index]=New_Node();
 42             now=next[now][index];
 43             s++;
 44         }
 45         num[now]=id;//将结束字符赋值为病毒编号
 46     }
 47     void Build_Fail()
 48     {
 49         queue<int >myqueue;
 50         for(int i=0;i < SON;++i)
 51             if(next[root][i] == -1)
 52                 next[root][i]=root;
 53             else
 54             {
 55                 fail[next[root][i]]=root;
 56                 myqueue.push(next[root][i]);
 57             }
 58         while(!myqueue.empty())
 59         {
 60             int now=myqueue.front();
 61             myqueue.pop();
 62             for(int i=0;i < SON;++i)
 63                 if(next[now][i] == -1)
 64                     next[now][i]=next[fail[now]][i];
 65                 else
 66                 {
 67                     fail[next[now][i]]=next[fail[now]][i];
 68                     myqueue.push(next[now][i]);
 69                 }
 70         }
 71     }
 72     int Query(const char *s)
 73     {
 74         int cnt=0;
 75         int now=root;
 76         bool vis[MAXN];
 77         memset(vis,false,sizeof(vis));
 78         while(*s != '\0')
 79         {
 80             int index=*s;
 81             now=next[now][index];
 82             int temp=now;
 83             while(temp != root && num[temp] != 0 && !vis[num[temp]])
 84             {
 85                 number[cnt++]=num[temp];
 86                 temp=fail[temp];
 87                 vis[num[temp]]=true;
 88             }
 89             s++;
 90         }
 91         return cnt;
 92     }
 93 };
 94 AC_Auto ac;
 95 char buf[10010];
 96 
 97 int main()
 98 {
 99     int N;
100     scanf("%d",&N);
101     ac.Initial();
102     for(int i=1;i <= N;++i)
103     {
104         scanf("%s",buf);
105         ac.Build_Trie(buf,i);
106     }
107     ac.Build_Fail();
108     int M;
109     scanf("%d",&M);
110     int total=0;
111     for(int i=1;i <= M;++i)
112     {
113         scanf("%s",buf);
114         int cnt=ac.Query(buf);
115         if(cnt > 0)
116         {
117             total++;
118             sort(ac.number,ac.number+cnt);
119             printf("web %d:",i);
120             for(int i=0;i < cnt;++i)
121                 printf(" %d",ac.number[i]);
122             printf("\n");
123         }
124     }
125     printf("total: %d\n",total);
126 
127     return 0;
128 }
View Code

 

posted @ 2018-09-12 20:25  HHHyacinth  阅读(147)  评论(0编辑  收藏  举报