/* FileName: 2896.cpp Author: ACb0y Date: 2010年12月30日11:39:54 Type: AC自动机 ProblemID: HDU 2896 病毒侵袭 Result: 3371920 2010-12-30 11:37:43 Accepted 2896 234MS 30004K 2447 B G++ ACb0y */ #include <iostream> #include <algorithm> #include <queue> using namespace std; struct node { node * fail; node * next[128]; int word; int order; }; int total; node * root; char key[205]; char web[10005]; node * get_node() { node * p = (node *)malloc(sizeof(node)); p->word = 0; p->order = 0; memset(p->next, NULL, sizeof(p->next)); return p; } /* 建Tire树 */ void insert(char * str, int order) { int len = strlen(str); node * p_cur = root; for (int i = 0; i < len; ++i) { int pos = str[i] - 31; if (p_cur->next[pos] == NULL) { p_cur->next[pos] = get_node(); } p_cur = p_cur->next[pos]; } p_cur->word = 1; p_cur->order = order; } /* 构建Tire树的fail指针 */ void build_fail() { root->fail = NULL; queue<node *> q; q.push(root); while (!q.empty()) { node * p_cur = q.front(); q.pop(); for (int i = 0; i < 128; ++i) { if (p_cur->next[i] != NULL) { if (p_cur == root) { p_cur->next[i]->fail = root; } else { //之前写成了temp = p_cur //然后一定RE,郁闷了很久。 node * temp = p_cur->fail; while (temp != NULL) { if (temp->next[i] != NULL) { p_cur->next[i]->fail = temp->next[i]; break; } temp = temp->fail; } if (temp == NULL) { p_cur->next[i]->fail = root; } } q.push(p_cur->next[i]); } } } } /* 多字符串匹配 */ void query(char * str, int order) { int ans[10]; int c = 0; node * p_cur = root; int len = strlen(str); for (int i = 0; i < len; ++i) { int pos = str[i] - 31; while (p_cur->next[pos] == NULL && p_cur != root) { p_cur = p_cur->fail; } p_cur = p_cur->next[pos]; if (p_cur == NULL) { p_cur = root; } node * temp = p_cur; while (temp != root && temp->word == 1) { ans[c++] = temp->order; temp = temp->fail; } } if (c > 0) { ++total; sort(ans, ans + c); printf("web %d:", order); for (int i = 0; i < c; ++i) { printf(" %d", ans[i]); } printf("/n"); } } void clear(node * root) { for (int i = 0; i < 128; ++i) { if (root->next[i] != NULL) { clear(root->next[i]); } } free(root); } int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); #endif int n; int cnt = 0; root = get_node(); scanf("%d/n", &n); while (n--) { gets(key); insert(key, ++cnt); } build_fail(); cnt = 0; scanf("%d/n", &n); while (n--) { gets(web); query(web, ++cnt); } printf("total: %d/n", total); clear(root); return 0; }