HDU 6208 The Dominator of Strings ——(青岛网络赛,AC自动机)

  最长的才可能成为答案,那么除了最长的以外全部insert到自动机里,再拿最长的去match,如果match完以后cnt全被清空了,那么这个最长串就是答案。事实上方便起见这个最长串一起丢进去也无妨,而且更好写(时间也没有慢特别多)。

  另外需要注意的一点是init()里头的memset只需要清空之前用过的节点而不是所有节点,这是经常被卡的一点。

  代码如下:

  1 #include <stdio.h>
  2 #include <algorithm>
  3 #include <string.h>
  4 #include <queue>
  5 #include <vector>
  6 using namespace std;
  7 const int MAX_N = 100000 + 50;
  8 const int MAX_Tot = 100000 + 50;
  9 
 10 struct Aho
 11 {
 12     struct state
 13     {
 14         int nxt[26];
 15         int fail,cnt;
 16     }stateTable[MAX_Tot];
 17 
 18     int size;
 19 
 20     queue<int> que;
 21 
 22     void init()
 23     {
 24         while(que.size()) que.pop();
 25         for(int i=0;i<size;i++)
 26         {
 27             memset(stateTable[i].nxt,0,sizeof(stateTable[i].nxt));
 28             stateTable[i].fail = stateTable[i].cnt = 0;
 29         }
 30         size = 1;
 31     }
 32 
 33     void insert(char *s)
 34     {
 35         int n = strlen(s);
 36         int now = 0;
 37         for(int i=0;i<n;i++)
 38         {
 39             char c = s[i];
 40             if(!stateTable[now].nxt[c-'a'])
 41                 stateTable[now].nxt[c-'a'] = size++;
 42             now = stateTable[now].nxt[c-'a'];
 43         }
 44         stateTable[now].cnt++;
 45     }
 46 
 47     void build()
 48     {
 49         stateTable[0].fail = -1;
 50         que.push(0);
 51 
 52         while(que.size())
 53         {
 54             int u = que.front();que.pop();
 55             for(int i=0;i<26;i++)
 56             {
 57                 if(stateTable[u].nxt[i])
 58                 {
 59                     if(u == 0) stateTable[stateTable[u].nxt[i]].fail = 0;
 60                     else
 61                     {
 62                         int v = stateTable[u].fail;
 63                         while(v != -1)
 64                         {
 65                             if(stateTable[v].nxt[i])
 66                             {
 67                                 stateTable[stateTable[u].nxt[i]].fail = stateTable[v].nxt[i];
 68                                 break;
 69                             }
 70                             v = stateTable[v].fail;
 71                         }
 72                         if(v == -1) stateTable[stateTable[u].nxt[i]].fail = 0;
 73                     }
 74                     que.push(stateTable[u].nxt[i]);
 75                 }
 76             }
 77         }
 78     }
 79 
 80     //bool mark[MAX_Tot];
 81     void Get(int u)
 82     {
 83         while(u)
 84         {
 85             if(stateTable[u].cnt == -1) break;
 86             stateTable[u].cnt = -1;
 87             u = stateTable[u].fail;
 88         }
 89     }
 90 
 91     int match(char *s)
 92     {
 93         //memset(mark, 0, sizeof mark);
 94         int n = strlen(s);
 95         int res = 0, now = 0;
 96         for(int i=0;i<n;i++)
 97         {
 98             char c = s[i];
 99             if(stateTable[now].nxt[c-'a']) now = stateTable[now].nxt[c-'a'];
100             else
101             {
102                 int p = stateTable[now].fail;
103                 while(p != -1 && stateTable[p].nxt[c-'a'] == 0) p = stateTable[p].fail;
104                 if(p == -1) now = 0;
105                 else now = stateTable[p].nxt[c-'a'];
106             }
107 
108             Get(now);
109         }
110         for(int i=1;i<size;i++) if(stateTable[i].cnt > 0) return 0;
111         return 1;
112     }
113 }aho;
114 
115 int T,n;
116 char s[MAX_N], t[MAX_N];
117 
118 int main()
119 {
120     int T;scanf("%d",&T);
121     while(T--)
122     {
123         vector<char> v;
124         aho.init();
125         scanf("%d",&n);
126         int maxn = 0;
127         for(int i=1;i<=n;i++)
128         {
129             scanf("%s",s);
130             //aho.insert(s);
131             int sz = strlen(s);
132             for(int j=0;j<sz;j++) v.push_back(s[j]);
133             v.push_back('#');
134             if(sz > maxn)
135             {
136                 maxn = sz;
137                 strcpy(t, s);
138             }
139         }
140         int tot = 0;
141         for(int i=0;i<v.size();i++)
142         {
143             if(v[i] == '#')
144             {
145                 s[tot++] = 0;
146                 tot = 0;
147                 if(strcmp(s, t)) aho.insert(s);
148             }
149             else s[tot++] = v[i];
150         }
151         aho.build();
152         int ans = aho.match(t);
153         if(ans) puts(t);
154         else puts("No");
155     }
156 }
原文地址:https://www.cnblogs.com/zzyDS/p/7570065.html