数据结构--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]!='\0'; ++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]!='\0'; ++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("\n");

147             }

148         }

149         BFS(root);

150         printf("total: %d\n",ans);

151     }

152     return 0;

153 }

 



 

你可能感兴趣的:(AC自动机)