hdu 2896 病毒侵袭

http://acm.hdu.edu.cn/showproblem.php?pid=2896

思路:建立字典树时,把字符串单词节点信息改为id就可以,然后计算失配函数,再查找哪一个上面的病毒字符串在下面的网站信息中出现,AC自动机。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <queue>
  4 #include <algorithm>
  5 #include <vector>
  6 #include <set>
  7 using namespace std;
  8 
  9 int n,m;
 10 char str[2000000];
 11 set<int>g;
 12 struct node
 13 {
 14     struct node *next[128],*fail;
 15     int v;
 16 }*root;
 17 
 18 void insert(char str[],int v)
 19 {
 20     struct node *head=root;
 21     struct node *temp;
 22     int k=strlen(str);
 23     for(int i=0; i<k; i++)
 24     {
 25         int x=(int)str[i];
 26         if(head->next[x]==NULL)
 27         {
 28             temp=(struct node *)malloc(sizeof(struct node));
 29             temp->v=0;
 30             temp->fail=root;
 31             for(int j=0; j<128; j++)
 32             {
 33                 temp->next[j]=NULL;
 34             }
 35             head->next[x]=temp;
 36         }
 37         head=head->next[x];
 38         if(i==k-1) head->v=v;
 39     }
 40 }
 41 
 42 void Build_AC()
 43 {
 44     struct node *head=root;
 45     queue<node *>q;
 46     q.push(root);
 47     while(!q.empty())
 48     {
 49         head=q.front();
 50         q.pop();
 51         for(int j=0; j<128; j++)
 52         {
 53             if(head->next[j])
 54             {
 55                 q.push(head->next[j]);
 56                 if(head==root)
 57                 {
 58                     head->next[j]->fail=root;
 59                 }
 60                 else
 61                 {
 62                     struct node *p=head->fail;
 63                     bool flag=false;
 64                     while(p->next[j]==NULL)
 65                     {
 66                         if(p==root)
 67                         {
 68                             flag=true;
 69                             break;
 70                         }
 71                         p=p->fail;
 72                     }
 73                     if(flag)
 74                     {
 75                         head->next[j]->fail=root;
 76                     }
 77                     else
 78                     {
 79                         head->next[j]->fail=p->next[j];
 80                     }
 81                 }
 82             }
 83         }
 84     }
 85 }
 86 
 87 void Find(char str[])
 88 {
 89     struct node *head=root,*p;
 90     int k=strlen(str);
 91     for(int i=0; i<k; i++)
 92     {
 93         int x=(int)str[i];
 94         while(head->next[x]==NULL&&head!=root) head=head->fail;
 95         if(head->next[x]==NULL) head=root;
 96         else head=head->next[x];
 97         p=head;
 98         while(p!=root)
 99         {
100             if(p->v)
101             g.insert(p->v);
102             p=p->fail;
103         }
104     }
105 }
106 
107 int main()
108 {
109     while(scanf("%d",&n)!=EOF)
110     {
111         root=(struct node*)malloc(sizeof(struct node));
112         root->fail=root;
113         root->v=0;
114         for(int i=0; i<128; i++)
115         {
116             root->next[i]=NULL;
117         }
118         for(int i=1; i<=n; i++)
119         {
120             scanf("%s",str);
121             insert(str,i);
122         }
123         Build_AC();
124         set<int>::iterator it;
125         int ans=0;
126         scanf("%d",&m);
127         for(int j=1; j<=m; j++)
128         {
129             g.clear();
130             scanf("%s",str);
131             Find(str);
132             if(g.size())
133             {
134                 ans++;
135                 printf("web %d:",j);
136                 for(it=g.begin(); it!=g.end(); it++)
137                 {
138                     printf(" %d",*it);
139                 }
140                 printf("\n");
141             }
142         }
143         printf("total: %d\n",ans);
144     }
145     return 0;
146 }
View Code

 

posted @ 2015-01-31 10:54  null1019  阅读(156)  评论(0编辑  收藏  举报