uva-1449-AC自动机

   题目链接https://vjudge.net/problem/UVA-1449

  题目大意:给出N(N<150)个长度不超过L(70)的匹配串和一个长度小于1e6的文本串,在文本串中找出出现次数最多的匹配串,如果有多个匹配串满足条件,按输入顺序依次输出。

AC自动机复杂度约为O((N+M)*L) //N为匹配串个数,M为文本串长度,L为匹配串平均长度,时间3s,可行

用了两个map方便统计字符串出现的次数和根据节点编号找到对应的字符串,注意这里统计时不必将AC[u].cnt清零;

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int MAX_T=1000006;
  4 const int MAX_NOD=150*70+15;
  5 const int MAX_SIG=26;
  6 const int MAX_P=71;
  7 map<string,int> M;
  8 map<int,string> _M;
  9 char T[MAX_T];
 10 struct node{
 11     int next[MAX_SIG];
 12     int fail,cnt;
 13 };
 14 struct aho
 15 {
 16     node AC[MAX_NOD];
 17     int size;
 18 
 19     int idx(char c){return c-'a';}
 20 
 21     void init()
 22     {
 23         for(int i=0;i<MAX_NOD;++i)
 24             memset(AC[i].next,0,sizeof(AC[i].next)),AC[i].cnt=0;
 25         size=1;
 26         AC[0].fail=-1;
 27     }
 28 
 29     void insert(char *S)
 30     {
 31         int n=strlen(S);
 32         int u=0;
 33         for(int i=0;i<n;++i)
 34         {
 35             int c=idx(S[i]);
 36             if(!AC[u].next[c]) AC[u].next[c]=size++;
 37             u=AC[u].next[c];
 38         }
 39         AC[u].cnt++;
 40         _M[u]=S;
 41         //cout<<"---"<<_M[u]<<" "<<AC[u].cnt<<endl;
 42     }
 43 
 44     void build_fail()
 45     {
 46         queue<int> q;
 47         q.push(0);
 48         AC[0].fail=-1;
 49         while(!q.empty()){
 50             int u=q.front();
 51             q.pop();
 52             for(int i=0;i<MAX_SIG;++i)
 53             {
 54                 if(AC[u].next[i]){
 55                     if(!u) AC[AC[u].next[i]].fail=0;
 56                     else{
 57                         int v=AC[u].fail;
 58                         while(v!=-1&&AC[v].next[i]==0) v=AC[v].fail;
 59                         if(v==-1) AC[AC[u].next[i]].fail=0;
 60                         else AC[AC[u].next[i]].fail=AC[v].next[i];
 61                     }
 62                     q.push(AC[u].next[i]);
 63                 }
 64             }
 65         }
 66     }
 67 
 68     void cal(int u)
 69     {
 70         while(u!=-1){//cout<<"ppp"<<endl;
 71             M[_M[u]]+=AC[u].cnt;
 72           //  AC[u].cnt=0;
 73             u=AC[u].fail;
 74         }
 75     }
 76 
 77     int solve(char *T)
 78     {
 79         int now=0;
 80         int n=strlen(T);
 81         for(int i=0;i<n;++i)
 82         {
 83             int c=idx(T[i]);
 84             if(AC[now].next[c]) now=AC[now].next[c];
 85             else{
 86                 int v=AC[now].fail;
 87                 while(v!=-1&&AC[v].next[c]==0) v=AC[v].fail;
 88                 if(v==-1){now=0;}
 89                 else{
 90                     now=AC[v].next[c];
 91                 }
 92             }
 93             if(AC[now].cnt){
 94                 cal(now);
 95             }
 96         }
 97     }
 98 };
 99 int main()
100 {
101     int n;
102     char P[MAX_P];
103     string x[155];
104     while(cin>>n&&n){
105         M.clear();
106         _M.clear();
107         aho a;
108         a.init();
109         for(int i=1;i<=n;++i)
110         {
111             cin>>P;
112             x[i]=P;
113             M[P]=0;
114             a.insert(P);
115         }
116         cin>>T;
117         a.build_fail();
118         int ans=0;
119         a.solve(T);
120         for(int i=1;i<=n;++i)
121             ans=max(ans,M[x[i]]);
122         cout<<ans<<endl;
123         for(int i=1;i<=n;++i)
124         {
125             if(M[x[i]]==ans) cout<<x[i]<<endl;
126         }
127     }
128     return 0;
129 }
130 /*
131 2
132 aba
133 bab
134 ababababac
135 6
136 beta
137 alpha
138 haha
139 delta
140 dede
141 tata
142 dedeltalphahahahototatalpha
143 0
144 */
原文地址:https://www.cnblogs.com/zzqc/p/8400385.html