码迷,mamicode.com
首页 > 其他好文 > 详细

【LA4670-Dominating Patterns】AC自动机

时间:2016-07-19 22:09:38      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:

http://acm.hust.edu.cn/vjudge/problem/19224

题意:给定n个单词,一个字符串,问哪些单词在字符串中出现的次数最多。单词aba,文本ababa,则aba出现了2次。

题解:每找到一个记得要顺着fail找到所有单词。

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<iostream>
  5 #include<queue>
  6 using namespace std;
  7 
  8 const int N=160,L=1000010;
  9 char s[L],ss[N][110];
 10 int cnt[N];
 11 int num,mx,n;
 12 struct node{
 13     int son[30];
 14     int id,fail;
 15 }a[N*110];
 16 queue<int> q;
 17 int maxx(int x,int y){return x>y ? x:y;}
 18 
 19 void clear(int x)
 20 {
 21     a[x].id=a[x].fail=0;
 22     memset(a[x].son,0,sizeof(a[x].son));
 23 }
 24 
 25 void trie(char *c,int id)
 26 {
 27     int l=strlen(c);
 28     int x=0;
 29     for(int i=0;i<l;i++)
 30     {
 31         int t=c[i]-a+1;
 32         if(!a[x].son[t])
 33         {
 34             num++;
 35             clear(num);
 36             a[x].son[t]=num;
 37         }
 38         x=a[x].son[t];
 39     }
 40     a[x].id=id;
 41 }
 42 
 43 void buildAC()
 44 {
 45     while(!q.empty()) q.pop();
 46     for(int i=1;i<=26;i++)
 47         if(a[0].son[i]) q.push(a[0].son[i]);
 48     while(!q.empty())
 49     {
 50         int x=q.front();q.pop();
 51         int fail=a[x].fail;
 52         for(int i=1;i<=26;i++)
 53         {
 54             int y=a[x].son[i];
 55             if(y)
 56             {
 57                 a[y].fail=a[fail].son[i];
 58                 q.push(y);
 59             }
 60             else a[x].son[i]=a[fail].son[i];
 61         }
 62     }
 63 }
 64 
 65 void find(char *c)
 66 {
 67     int l=strlen(c);
 68     int x=0;
 69     for(int i=0;i<l;i++)
 70     {
 71         int t=c[i]-a+1;
 72         if(!a[x].son[t]) x=0;
 73         else x=a[x].son[t];
 74         int p=x;
 75         while(p)
 76         {
 77             if(a[p].id) cnt[a[p].id]++;
 78             p=a[p].fail;
 79         }
 80     }
 81 }
 82 
 83 int main()
 84 {
 85     freopen("a.in","r",stdin);
 86     freopen("a.out","w",stdout);
 87     while(1)
 88     {
 89         scanf("%d",&n);
 90         if(!n) return 0;
 91         num=mx=0;
 92         clear(0);
 93         memset(cnt,0,sizeof(cnt));
 94         for(int i=1;i<=n;i++)
 95         {
 96             scanf("%s",ss[i]);
 97             trie(ss[i],i);
 98         }
 99         buildAC();
100         scanf("%s",s);
101         find(s);
102         for(int i=1;i<=n;i++) mx=maxx(mx,cnt[i]);
103         printf("%d\n",mx);
104         for(int i=1;i<=n;i++)
105         {
106             if(mx==cnt[i]) printf("%s\n",ss[i]);
107         }
108     }
109     return 0;
110 }

 

【LA4670-Dominating Patterns】AC自动机

标签:

原文地址:http://www.cnblogs.com/KonjakJuruo/p/5686416.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!