数据结构--AC自动机--hdu 2896

病毒侵袭

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

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
 
Source




AC自动机模板题。。。。。。
tips:
       ASCII码的不可见字符,他们是0~31,以及127。
代码:
  1 #include "queue"  //hdu 2896
  2 #include "cstdio"
  3 #include "cstring"
  4 #include "algorithm"
  5 using namespace std;
  6 
  7 int a[1005][4];  //a[i][]记录第i个网站所包含的病毒编号
  8 bool flag[505];
  9 
 10 struct node
 11 {
 12     int count;
 13     node *fail;
 14     node *next[95];  //ASCII码可见字符为32~126,共95个;
 15     node()
 16     {
 17         count = 0;
 18         fail = NULL;
 19         memset(next,NULL,sizeof(next));
 20     }
 21 };
 22 
 23 void Insert(node *root,char *s,int k)
 24 {
 25     node *p = root;
 26     int i,index;
 27     for(i=0; s[i]!=''; ++i)
 28     {
 29         index = s[i]-32;
 30         if(p->next[index]==NULL)
 31             p->next[index] = new node();
 32         p = p->next[index];
 33     }
 34     p->count = k;
 35 }
 36 
 37 void Build_ac_automation(node *root)  //建立失败指针
 38 {
 39     int i;
 40     root->fail = NULL;
 41     node *p,*temp;
 42     queue<node *> q;
 43     q.push(root);
 44     while(!q.empty())   //bfs构造失败指针
 45     {
 46         temp = q.front();
 47         q.pop();
 48         p = NULL;
 49         for(i=0; i<95; ++i)
 50         {
 51             if(temp->next[i]==NULL) continue;
 52             if(temp==root)
 53             {
 54                 temp->next[i]->fail = root;
 55                 q.push(temp->next[i]);
 56                 continue;
 57             }
 58             p = temp->fail;
 59             while(p!=NULL)
 60             {
 61                 if(p->next[i]!=NULL){
 62                     temp->next[i]->fail = p->next[i];
 63                     break;
 64                 }
 65                 p = p->fail;
 66             }
 67             if(p==NULL)
 68                 temp->next[i]->fail = root;
 69             q.push(temp->next[i]);
 70         }
 71     }
 72 }
 73 
 74 void Query(node *root,char *s,int *a)
 75 {
 76     int k = 1;
 77     int i,index;
 78     node *p = root;
 79     memset(flag,false,sizeof(flag));
 80     for(i=0; s[i]!=''; ++i)
 81     {
 82         index = s[i]-32;
 83         while(p->next[index]==NULL && p!=root)
 84             p = p->fail;
 85         p = p->next[index];
 86         p = (p==NULL) ? root:p;
 87         node *temp = p;
 88         while(temp!=root && flag[temp->count]!=true)
 89         {
 90             if(temp->count!=0){
 91                 a[k++] = temp->count;
 92                 flag[temp->count] = true;
 93             }
 94             temp = temp->fail;
 95         }
 96     }
 97     a[0] = k-1;
 98 }
 99 
100 void BFS(node *p)
101 {
102     int i;
103     for(i=0; i<95; ++i)
104     {
105         if(p->next[i]!=NULL)
106             BFS(p->next[i]);
107     }
108     delete p;
109 }
110 
111 int main()
112 {
113     int i;
114     int n;
115     char s[205];
116     char str[10010];
117     while(scanf("%d",&n)!=-1)
118     {
119         node *root = new node();
120         getchar();
121         for(i=1 ;i<=n; ++i)
122         {
123             scanf("%s",s);
124             Insert(root,s,i);
125         }
126         Build_ac_automation(root);
127         int m;
128         scanf("%d",&m);
129         getchar();
130         memset(a,0,sizeof(a));
131         for(i=1; i<=m; ++i)
132         {
133             scanf("%s",str);
134             Query(root,str,a[i]);
135         }
136         int ans = 0;
137         for(i=1; i<=m; ++i)
138         {
139             if(a[i][0]!=0)
140             {
141                 ans++;
142                 printf("web %d:",i);
143                 sort(a[i]+1,a[i]+4);
144                 for(int k=4-a[i][0]; k<=3; ++k)
145                     printf(" %d",a[i][k]);
146                 printf("
");
147             }
148         }
149         BFS(root);
150         printf("total: %d
",ans);
151     }
152     return 0;
153 }


原文地址:https://www.cnblogs.com/ruo-yu/p/4411984.html