Loading

HDU 3065:病毒侵袭持续中(AC自动机)

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

题意:中文题意。

思路:直接插入然后用一个数组记录id和cnt,因为n只有1000,可以开一个数组判断第几个字符串出现过的次数,然后输出就好了。

坑点:多组输入!!!然后因为new出来的空间要自己释放,因此需要用一个vector装起来(似乎多此一举),最后delete掉。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <vector>
  5 #include <queue>
  6 using namespace std;
  7 #define N 1010
  8 #define M 2000010
  9 #define TOL 128
 10 typedef struct Node {
 11     Node* next[TOL];
 12     Node* fail;
 13     int id, cnt;
 14     Node () {
 15         for(int i = 0; i < TOL; i++) next[i] = NULL;
 16         id = cnt = 0;
 17         fail = NULL;
 18     }
 19 } node;
 20 
 21 char s[N][55], str[M];
 22 
 23 class AC_DFA {
 24 
 25 private:
 26     node* root;
 27     int ans[N], n;
 28     vector<node*> dic;
 29 
 30 public:
 31     AC_DFA(int now) {
 32         dic.clear();
 33         root = new Node();
 34         dic.push_back(root);
 35         n = now;
 36         memset(ans, 0, sizeof(ans));
 37     }
 38 
 39     ~AC_DFA() {
 40         for(int i = 0; i < dic.size(); i++) delete dic[i];
 41     }
 42 
 43     void insert(char *s, int id) {
 44         int len = strlen(s);
 45         node* now = root;
 46         for(int i = 0; i < len; i++) {
 47             char c = s[i];
 48             if(now->next[c] == NULL) now->next[c] = new Node(), dic.push_back(now->next[c]);
 49             now = now->next[c];
 50         }
 51         now->id = id;
 52         now->cnt++;
 53     }
 54 
 55     void build() {
 56         queue<node *> que;
 57         que.push(root);
 58         root->fail = NULL;
 59         while(!que.empty()) {
 60             node* now = que.front();
 61             que.pop();
 62             for(int i = 0; i < TOL; i++) {
 63                 if(now->next[i]) {
 64                     node* p = now->fail;
 65                     while(p && p->next[i] == NULL) p = p->fail;
 66                     if(p) now->next[i]->fail = p->next[i];
 67                     else now->next[i]->fail = root;
 68                     que.push(now->next[i]);
 69                 } else {
 70                     if(now == root) now->next[i] = root;
 71                     else now->next[i] = now->fail->next[i];
 72                 }
 73             }
 74         }
 75     }
 76 
 77     void match(char *s) {
 78         int len = strlen(s);
 79         node *now = root, *p;
 80         for(int i = 0; i < len; i++) {
 81             char c = s[i];
 82             while(now != root && now->next[c] == NULL)
 83                 now = now->fail;
 84             now = now->next[c];
 85             p = now;
 86             while(p) {
 87                 if(p->cnt) ans[p->id] += p->cnt;
 88                 p = p->fail;
 89             }
 90         }
 91     }
 92 
 93     void print() {
 94         for(int i = 1; i <= n; i++)
 95             if(ans[i]) printf("%s: %d\n", s[i], ans[i]);
 96     }
 97 
 98 };
 99 
100 int main() {
101     int n;
102     while(~scanf("%d", &n)) {
103         AC_DFA ac(n);
104         for(int i = 1; i <= n; i++) {
105             scanf("%s", s[i]);
106             ac.insert(s[i], i);
107         }
108         scanf("%s", str);
109         ac.build();
110         ac.match(str);
111         ac.print();
112     }
113     return 0;
114 }

 

posted @ 2017-03-21 12:56  Shadowdsp  阅读(130)  评论(0编辑  收藏  举报