题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3065

思路分析:问题需要模式匹配多个模式串,需要注意的是模式串会包含和重叠,需要对AC自动机的匹配过程进行修改,对于每个节点,需要从该节点的失败指针回溯,

如果失败指针回溯后的节点为某个模式串的最后一个节点,则匹配了另一个模式串;

代码如下:

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; const int KIND = ;
const int MAX_NODE = * ;
const int MAX_N = + ;
const int MAX_M = + ;
char str[MAX_M];
int visited[MAX_N];
int vir_match[MAX_N];
char vir[MAX_N][]; struct Trie {
int root, count;
int next[MAX_NODE][KIND], fail[MAX_NODE], end[MAX_NODE];
void Init()
{
count = ;
root = NewNode();
}
int NewNode()
{
for (int i = ; i < KIND; ++i)
next[count][i] = -;
end[count] = -;
return count++;
} void Insert(char *str, int id)
{
int i = , k = ;
int now = root; while (str[i])
{
k = str[i];
if (next[now][k] == -)
next[now][k] = NewNode();
now = next[now][k];
++i;
}
end[now] = id;
} void BuildAutomaton()
{
queue<int> Q; fail[root] = -;
Q.push(root);
while (!Q.empty())
{
int now = Q.front();
int p = -;
Q.pop(); for (int i = ; i < KIND; ++i)
{
if (next[now][i] != -)
{
if (now == root)
fail[next[now][i]] = root;
else
{
p = fail[now];
while (p != -)
{
if (next[p][i] != -)
{
fail[next[now][i]] = next[p][i];
break;
}
p = fail[p];
}
if (p == -)
fail[next[now][i]] = root;
}
Q.push(next[now][i]);
}
}
}
} int Match(char *str)
{
int i = , k = , vir_count = ;
int p = root; while (str[i])
{
k = str[i];
while (next[p][k] == - && p != root)
p = fail[p];
p = next[p][k];
p = (p == -) ? root : p; int temp = p;
while (temp != root)
{
if (end[temp] != -)
{
if (visited[end[p]] == )
vir_match[vir_count++] = end[p];
visited[end[p]]++;
}
temp = fail[temp];
}
++i;
}
return vir_count;
}
};
Trie root; int main()
{
int vir_num = ;
int match_count = ; while (scanf("%d\n", &vir_num) != EOF)
{
root.Init();
memset(vir_match, , sizeof(vir_match));
memset(visited, , sizeof(visited));
for (int i = ; i < vir_num; ++i)
{
gets(str);
strcpy(vir[i], str);
root.Insert(str, i + );
} match_count = ;
root.BuildAutomaton();
gets(str);
int ans = root.Match(str);
sort(vir_match, vir_match + ans);
if (ans)
{
for (int j = ; j < ans - ; ++j)
printf("%s: %d\n", vir[vir_match[j] - ], visited[vir_match[j]]);
printf("%s: %d\n", vir[vir_match[ans - ] - ],
visited[vir_match[ans - ]]);
}
}
return ;
}

hdoj 3065 病毒侵袭持续中(AC自动机)的更多相关文章

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

    题目链接 Problem Description 小t非常感谢大家帮忙解决了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的"万恶之源".这是一个庞大的病毒 ...

  2. hdu3065 病毒侵袭持续中 AC自动机入门题 N(N <= 1000)个长度不大于50的模式串(保证所有的模式串都不相同), 一个长度不大于2000000的待匹配串,求模式串在待匹配串中的出现次数。

    /** 题目:hdu3065 病毒侵袭持续中 链接:http://acm.hdu.edu.cn/showproblem.php?pid=3065 题意:N(N <= 1000)个长度不大于50的 ...

  3. hdu----(3065)病毒侵袭持续中(AC自动机)

    病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  4. HDU3065 病毒侵袭持续中 —— AC自动机

    题目链接:https://vjudge.net/problem/HDU-3065 病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others)    Memory Li ...

  5. HDU-3065 病毒侵袭持续中 AC自动机又是一板子!

    病毒侵袭持续中 上一题是求出现多少病毒输出病毒序号,而这题输出每个病毒出现的次数.这题有字典树基础都能做出来,把叶子节点用相应的编号标记起来,匹配的时候遍历到叶子节点用一个数组把次数存起来就行了. 有 ...

  6. [hdu3065]病毒侵袭持续中(AC自动机)

    题意:给出多种病毒的号码和特征码,计算在某串中各病毒匹配的次数. 解题关键:AC自动机模板题,多组输入坑人. #include<bits/stdc++.h> using namespace ...

  7. HDU 3065 病毒侵袭持续中

    HDU 3065 病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  8. hdu 3065 病毒侵袭持续中【AC自动机】

    <题目链接> 题目大意: 小t非常感谢大家帮忙解决了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的“万恶之源”.这是一个庞大的病毒网站,他有着好多好多的病毒,但是 ...

  9. HDU 3065 病毒侵袭持续中(AC自己主动机)

    题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=3065 Problem Description 小t非常感谢大家帮忙攻克了他的上一个问题.然而病毒侵袭 ...

随机推荐

  1. win7(32 bit) + IE8 环境,IE8无法弹窗(错误提示:“此网页上的错误可能会使它无法正确运行”),有关的系统注册信息损坏——解决方法

    错误截图如下:   IE有关的系统注册信息损坏,导致IE无法正常弹窗.   解决办法:重新注册与IE有关的DLL文件,具体如下: 1.以管理员身份运行附件脚本(新建txt文件,将下面代码复制到txt文 ...

  2. ButterKnife使用小结

    项目官网:http://jakewharton.github.io/butterknife/ Github主页:https://github.com/JakeWharton/butterknife 这 ...

  3. 高效的数组去重(js)

    function uniqueArray(data){ data = data || []; var a = {}; for (var i=0; i<data.length; i++) { va ...

  4. PhpStorm 10.0 激活方式

    随着 JetBrains 新版本的发布,注册机已然不行了.然而,道高一尺,魔高一丈.IntelliJ IDEA开源社区 提供了如下通用激活方法:注册时选择License server填写http:// ...

  5. 一个简单的web框架实现

    一个简单的web框架实现 #!/usr/bin/env python # -- coding: utf-8 -- __author__ = 'EchoRep' from wsgiref.simple_ ...

  6. 转: requestAnimationFrame,Web中写动画的另一种选择

    HTML5/CSS3时代,我们要在web里做动画选择其实已经很多了: 你可以用CSS3的animattion+keyframes; 你也可以用css3的transition; 你还可以用通过在canv ...

  7. Github Blog 搭建手册

    http://www.ilehao.com/blog/2012/11/11/github-blog-config/ http://www.freebuf.com/articles/web/25613. ...

  8. mysql 批量删除分区

    alter table titles drop partition p01; use zabbix; mysql> source drop_par.sql [oracle@oadb mysql] ...

  9. BZOJ 2002 [Hnoi2010]Bounce 弹飞绵羊(动态树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2002 [题目大意] 给出一片森林,操作允许更改一个节点的父亲,查询一个节点的深度. [ ...

  10. 第七届河南省赛F.Turing equation(模拟)

    10399: F.Turing equation Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 151  Solved: 84 [Submit][St ...