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('\n'); 96 else putchar(' '); 97 } 98 } 99 100 void print() { 101 printf("total: %d\n", 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 }