HDU 2896:病毒侵袭(AC自动机)

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

题意:中文题意。

思路:AC自动机模板题。主要在于字符有128种,输出还要排序和去重!

注意是“total”不是“totol”!!!因为这个Debug了好久。

还有结点是new的,不然MLE。

主要用来测试模板,看了两个,发现没有注释掉的效率高点。

  1 #include <cstring>
  2 #include <algorithm>
  3 #include <cstdio>
  4 #include <vector>
  5 #include <queue>
  6 using namespace std;
  7 #define N 100010
  8 #define TOL 128
  9 
 10 typedef struct Node {
 11     Node* next[TOL];
 12     Node* fail;
 13     int id;
 14     Node() {
 15         for(int i = 0; i < TOL; i++) next[i] = NULL;
 16         fail = NULL; id = 0;
 17     }
 18 } node;
 19 
 20 class AC_DFA {
 21 
 22     private:
 23         int ans;
 24         node *root;
 25 
 26     public:
 27         AC_DFA() {
 28             ans = 0; root = new Node();
 29         }
 30 
 31         void insert(char* s, int id) {
 32             node* now = root;
 33             int len = strlen(s);
 34             for(int i = 0; i < len; i++) {
 35                 char c = s[i];
 36                 if(now->next[c] == NULL) now->next[c] = new Node();
 37                 now = now->next[c];
 38             }
 39             now->id = id;
 40         }
 41 
 42         void build() {
 43             root->fail = NULL;
 44             queue<node*> que;
 45             que.push(root);
 46             while(!que.empty()) {
 47                 node* now = que.front(); que.pop();
 48                 for(int i = 0; i < TOL; i++) {
 49                     if(now->next[i]) {
 50                         node* p = now->fail;
 51                         while(p && p->next[i] == NULL) p = p->fail;
 52                         if(p) now->next[i]->fail = p->next[i];
 53                         else now->next[i]->fail = root;
 54                         que.push(now->next[i]);
 55                     } else {
 56                         if(now == root) now->next[i] = root;
 57                         else now->next[i] = now->fail->next[i];
 58                     }
 59                 }
 60             }
 61         }
 62 
 63         void match(char *s, int id) {
 64             bool flag = 0;
 65             int len = strlen(s);
 66             vector<int> tol;
 67             node* now = root; node* p;
 68             for(int i = 0; i < len; i++) {
 69                 char c = s[i];
 70                 while(now->next[c] == NULL && now != root) now = now->fail;
 71                 now = now->next[c];
 72                 p = now;
 73                 while(p) {
 74                     if(p->id) tol.push_back(p->id), flag = 1;
 75                     p = p->fail;
 76                 }
 77                 /*
 78                 char c = s[i];
 79                 now = now->next[c];
 80                 p = now;
 81                 while(p) {
 82                     if(p->id) tol.push_back(p->id), flag = 1;
 83                     p = p->fail;
 84                 }
 85                 */
 86             }
 87 
 88             if(!flag) return ;
 89             sort(tol.begin(), tol.end());
 90             int cnt = unique(tol.begin(), tol.end()) - tol.begin(); // 去重
 91             ans++;
 92             printf("web %d: ", id);
 93             for(int i = 0; i < cnt; i++) {
 94                 printf("%d", tol[i]);
 95                 if(i == cnt - 1) putchar('
');
 96                 else putchar(' ');
 97             }
 98         }
 99 
100         void print() {
101             printf("total: %d
", ans); // 不是totol
102         }
103 
104 };
105 
106 int main() {
107 
108     AC_DFA ac;
109     char s[10010];
110     int n; scanf("%d", &n);
111     for(int i = 1; i <= n; i++) {
112         scanf("%s", s); ac.insert(s, i);
113     }
114     ac.build();
115     int m; scanf("%d", &m);
116     for(int i = 1; i <= m; i++) {
117         scanf("%s", s); ac.match(s, i);
118     }
119     ac.print();
120     return 0;
121 }
原文地址:https://www.cnblogs.com/fightfordream/p/6590094.html