【HDOJ】2896 病毒侵袭

AC自动机模板题。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <queue>
  5 using namespace std;
  6
  7 #define TRIEN 128
  8 #define MAXN  505
  9
 10 typedef struct Trie {
 11     int in;
 12     Trie *fail;
 13     Trie *next[TRIEN];
 14     Trie() {
 15         in = 0;
 16         fail = NULL;
 17         memset(next, 0, sizeof(next));
 18     }
 19 } Trie;
 20
 21 Trie *root;
 22 char src[205], des[10005];
 23 bool visit[MAXN];
 24
 25 void create(char str[], int in) {
 26     int i = 0, id;
 27     Trie *p = root, *q;
 28
 29     while (str[i]) {
 30         id = str[i];
 31         ++i;
 32         if (p->next[id] == NULL) {
 33             q = new Trie();
 34             p->next[id] = q;
 35         }
 36         p = p->next[id];
 37     }
 38     p->in = in;
 39 }
 40
 41 void build_fail() {
 42     int i;
 43     Trie *p, *q;
 44     queue<Trie *> que;
 45
 46     for (i=0; i<TRIEN; ++i) {
 47         if (root->next[i]) {
 48             root->next[i]->fail = root;
 49             que.push(root->next[i]);
 50         }
 51     }
 52
 53     while (!que.empty()) {
 54         p = que.front();
 55         que.pop();
 56         for (i=0; i<TRIEN; ++i) {
 57             if (p->next[i]) {
 58                 q = p->fail;
 59                 while (q != NULL) {
 60                     if (q->next[i]) {
 61                         p->next[i]->fail = q->next[i];
 62                         break;
 63                     }
 64                     q = q->fail;
 65                 }
 66                 if (q == NULL)
 67                     p->next[i]->fail = root;
 68                 que.push(p->next[i]);
 69             }
 70         }
 71     }
 72 }
 73
 74 void search() {
 75     int i = 0, id;
 76     Trie *p = root, *tmp;
 77
 78     while (des[i]) {
 79         id = des[i];
 80         ++i;
 81         while (p->next[id]==NULL && p!=root)
 82             p = p->fail;
 83         p = p->next[id];
 84         if (p == NULL)
 85             p = root;
 86         tmp = p;
 87         while (tmp != root) {
 88             visit[tmp->in] = true;
 89             tmp = tmp->fail;
 90         }
 91     }
 92 }
 93
 94 void del(Trie *t) {
 95     if (t == NULL)
 96         return ;
 97     for (int i=0; i<TRIEN; ++i)
 98         del(t->next[i]);
 99     delete t;
100 }
101
102 int main() {
103     int n, m, cnt, total;
104     int i;
105
106     while (scanf("%d",&n) != EOF) {
107         root = new Trie();
108         for (i=1; i<=n; ++i) {
109             scanf("%s", src);
110             create(src, i);
111         }
112         build_fail();
113         scanf("%d", &m);
114         total = 0;
115         for (i=1; i<=m; ++i) {
116             scanf("%s", des);
117             memset(visit, false, sizeof(visit));
118             search();
119             cnt = 0;
120             for (int j=1; j<=n; ++j) {
121                 if (visit[j]) {
122                     if (!cnt)
123                         printf("web %d:", i);
124                     ++cnt;
125                     printf(" %d", j);
126                 }
127             }
128             if (cnt) {
129                 printf("\n");
130                 ++total;
131             }
132         }
133         printf("total: %d\n", total);
134         del(root);
135     }
136
137     return 0;
138 }

【HDOJ】2896 病毒侵袭,布布扣,bubuko.com

时间: 2024-08-02 02:41:38

【HDOJ】2896 病毒侵袭的相关文章

hdoj 2896 病毒侵袭 【AC自动机 基础题】

病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 15893    Accepted Submission(s): 4055 Problem Description 当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻....在这样的时刻,人们却异常兴奋--我们能在有生之年看到500年一遇的世界奇观,那是多么幸福的事

hdoj 2896 病毒侵袭(AC自动机)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2896 思路分析:题目为模式匹配问题,对于一个给定的字符串,判断能匹配多少个模式:该问题需要静态建树,另外需要对AC自动机的模板加以修改, 对于每个匹配的模式的最后一个单词的fail指针指向root,即可实现一个字符串进行多次模式匹配: 代码如下: #include <queue> #include <cstdio> #include <cstring> #include &

HDU 2896 病毒侵袭 AC自动机题解

本题是在text里面查找key word的增强版,因为这里有多个text. 那么就不可以简单把Trie的叶子标志记录修改成-1进行加速了,可以使用其他技术,我直接使用个vis数组记录已经访问过的节点,达到加速效果,速度还算挺快的. 不过看discuss里面有人直接使用Trie,做出了140ms的速度,而且他的程序严格来说并不正确,可见本题的数据很水啊.Trie的时间效率肯定比AC自动机低,但是在数据很水的特殊情况下,Trie的速度也可以很快的. 注意两个细节: 1 病毒也需要安装顺序输出,不小心

HDU 2896 病毒侵袭

二次联通门 : HDU 2896 病毒侵袭 /* HDU 2896 病毒侵袭 AC自动机 此题太坑啦... 用G++交会无限MLE 行尾不输出回车会无限WA.. 写的程序没错 却交了N遍.. */ #include <cstring> #include <cstdio> #include <queue> #define Max 100090 void read (int &now) { now = 0; register char word = getchar

hdu 2896 病毒侵袭 AC自动机(查找包含哪些子串)

病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 19465    Accepted Submission(s): 4814 Problem Description 当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻....在这样的时刻,人们却异常兴奋——我们能在有生之年看到500年一遇的世界奇观,那是多么幸福的事儿

HDOJ 题目2896 病毒侵袭(AC自动机)

病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 15352    Accepted Submission(s): 3901 Problem Description 当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻....在这样的时刻,人们却异常兴奋--我们能在有生之年看到500年一遇的世界奇观,那是多么幸福的事

[hdu 2896] 病毒侵袭 [ac自动机][病毒特征码匹配]

病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 20728    Accepted Submission(s): 5058 Problem Description 当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻....在这样的时刻,人们却异常兴奋--我们能在有生之年看到500年一遇的世界奇观,那是多么幸福的事

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

病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 13063    Accepted Submission(s): 3378 Problem Description 当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻....在这样的时刻,人们却异常兴奋--我们能在有生之年看到500年一遇的世界奇观,那是多么幸福的事

HDU 2896 病毒侵袭(AC自动机模版题)

AC自动模版题,中文题目就不叙述题意了啊. AC自动主要是构造出字典树之后找到fail指针的跳转,类似于KMP里面的next数组的跳转啊,注意这里是多模式跳转.意思就是这个串跳到下一个串的什么位置啊. 先帖一下,做多了再一起总结吧. 病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 11347    Accepted Submi