hdu 2896 病毒侵袭 ac自动机
/*
hdu 2896 病毒侵袭 ac自动机
从题意得知,模式串中没有重复的串出现,所以结构体中可以将last[](后缀链接)数组去掉
last[]数组主要是记录具有相同后缀模式串的末尾节点编号 。本题中主要是计算每一个模式串
在主串中有没有出现过,而不是计算出现过多少次,所以将last[]数组省掉....
*/
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define N 210*500
using namespace std;
class AC_atomata
{
public:
int trie[N][], f[N], val[N];
int vis[];
int nodeN;
int total;
queue<int>q;
void init()
{
nodeN=;
val[]=;
total=;
while(!q.empty()) q.pop();
memset(trie[], , sizeof(trie[]));
}
void build(char *str, int index);//建立trie树
void getFail();//失配函数
void find(char *T, int n, int index);//查找函数
}; void AC_atomata::build(char *str, int index)
{
int i, u;
for(i=, u=; str[i]; ++i)
{
int ch=str[i];
if(!trie[u][ch])
{
trie[u][ch]=++nodeN;
memset(trie[nodeN], , sizeof(trie[nodeN]));
}
u=trie[u][ch];
val[u]=;
}
val[u]=index;
} void AC_atomata::getFail()
{
int r, u, v, i;
f[]=;
for(i=; i<; ++i)
{
if(trie[][i])
{
q.push(trie[][i]);
f[trie[][i]]=;
}
}
while(!q.empty())
{
r=q.front();
q.pop();
for(i=; i<; ++i)
{
u=trie[r][i];
if(!u) continue;
q.push(u);
v=f[r];
while(v && !trie[v][i]) v=trie[v][i];
f[u]=trie[v][i];
}
}
} void AC_atomata::find(char *T, int n, int index)
{
int i, u;
int cnt=, v[];
memset(v, , sizeof(v));
memset(vis, , sizeof(vis));//每一次查找将数组初始化,开始忘记初始化了, 哇了好多次
for(i=, u=; T[i]; ++i)
{
int ch=T[i];
while(u && !trie[u][ch]) u=f[u];
u=trie[u][ch];
if(val[u] && !vis[val[u]])
{
v[cnt++]=val[u];
vis[val[u]]=;
if(cnt>) break;
}
}
if(cnt>)
{
++total;
printf("web %d:", index);
sort(v, v+);
for(i=; i<; ++i)
if(v[i]) printf(" %d", v[i]);
printf("\n");
}
} AC_atomata ac;
char T[], s[]; int main()
{
int n, m, i;
while(scanf("%d", &n)!=EOF)
{
ac.init();
for(i=; i<=n; ++i)
{
scanf("%s", s);
ac.build(s, i);
}
ac.getFail();
scanf("%d", &m);
for(i=; i<=m; ++i)
{
scanf("%s", T);
ac.find(T, n, i);
}
printf("total: %d\n", ac.total);
}
return ;
}
/*
上面的程序过了,感觉数据很水....
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define N 100005
#define M 505
using namespace std;
int n, m;
class AC_atomata
{
public:
int trie[N][128], fail[N];
int cnt;
int vis[M];//标记边
int nodeN;//节点数
int val[N];//标记字符节点是否为单词末尾
queue<int>q;
void init();
void build(char *T, int index) ;
void getFail();
void find(char *S, int index);
}; void AC_atomata:: init()
{
while(!q.empty()) q.pop();
memset(trie[0], 0, sizeof(trie[0]));
nodeN=0;
cnt=0;
memset(val, 0, sizeof(val));
} void AC_atomata:: build(char *T, int index)
{
int i, u=0;
for(i=0; T[i]; ++i)
{
if(trie[u][T[i]]==0)
{
trie[u][T[i]]=++nodeN;
memset(trie[nodeN], 0, sizeof(trie[nodeN]));
}
val[u]=0;
u=trie[u][T[i]];
}
val[u]=index;
} void AC_atomata:: getFail()
{
int r, u, v;
int c, root=0;
fail[root]=0;
for(c=0; c<128; ++c)
{
if(v=trie[root][c])
{
fail[v]=root;
q.push(v);
}
}
while(!q.empty())
{
r=q.front(); q.pop();
for(c=0; c<128; ++c)
{
u=trie[r][c];
if(!u)//该节点不存在,也就是查找过程中每一个节点都是平等的
trie[r][c]=trie[fail[r]][c];
else
{
fail[u]=trie[fail[r]][c];
q.push(u);
}
}
}
} void AC_atomata:: find(char *S, int index)
{
int cur, root, count=0;
cur=root=0;
memset(vis, 0, sizeof(vis));
for(int i=0; S[i]; ++i)
{
cur=trie[cur][S[i]];
int next=cur;
//这个while循环就是last[]数组实现的功能,只不过是last[]数组记录的总是单词结尾字符的节点的编号
//而我们通过沿着 next 节点的失配方向一直搜索, 也可以寻找到 以next节点所对应字符结尾的单词
while(next!=root)
{
if(val[next])
{
vis[val[next]]=1;
count++;
}
next=fail[next];
}
}
if(count>0)
{
++cnt;
printf("web %d:", index);
for(int i=1; i<=n; ++i)
if(vis[i])
printf(" %d", i);
printf("\n");
}
} char t[205], s[10005];
AC_atomata ac;
int main()
{
int i;
while(scanf("%d", &n)!=EOF)
{
ac.init();
for(i=1; i<=n; ++i)
{
scanf("%s", t);
ac.build(t, i);
}
ac.getFail();
scanf("%d", &m) ;
for(i=1; i<=m; ++i)
{
scanf("%s", s);
ac.find(s, i);
}
printf("total: %d\n", ac.cnt);
}
return 0;
}
hdu 2896 病毒侵袭 ac自动机的更多相关文章
- hdu 2896 病毒侵袭 AC自动机(查找包含哪些子串)
病毒侵袭 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- hdu 2896 病毒侵袭 AC自动机 基础题
病毒侵袭 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- HDU 2896 病毒侵袭 (AC自己主动机)
pid=2896">http://acm.hdu.edu.cn/showproblem.php?pid=2896 病毒侵袭 Time Limit: 2000/1000 MS (Java ...
- hdu 2896 病毒侵袭_ac自动机
题意:略 思路:套用ac自动机模板 #include <iostream> #include<cstdio> #include<cstring> using nam ...
- HDU 2896 病毒侵袭 AC自己主动机题解
本题是在text里面查找key word的增强版.由于这里有多个text. 那么就不能够简单把Trie的叶子标志记录改动成-1进行加速了,能够使用其它技术.我直接使用个vis数组记录已经訪问过的节点, ...
- HDU 2896 病毒侵袭(AC自动机水)
病毒侵袭 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- HDU 2896 病毒侵袭(AC自动机)
病毒侵袭 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- HDU 2896 病毒侵袭【AC自动机】
<题目链接> Problem Description 当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻....在这样的时刻,人们却异常兴奋——我们能在有生之年看到500年一 ...
- hdu2896 病毒侵袭 ac自动机
地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=2896 题目: 病毒侵袭 Time Limit: 2000/1000 MS (Java/Othe ...
随机推荐
- 01、AngularJs简介
AngularJs致力于减轻程序员在开发Ajax应用过程的痛苦.做前端的童鞋都知道,当在开发Ajax应用时,我们在与后台交互的同时,还在不断的手动操作Dom,诸如自己组装后台数据,渲染Html标签生成 ...
- 基于OpenCv的人脸检测、识别系统学习制作笔记之三
1.在windows下编写人脸检测.识别系统.目前已完成:可利用摄像头提取图像,并将人脸检测出来,未进行识别. 2.在linux下进行编译在windows环境下已经能运行的代码. 为此进行了linux ...
- (原创)古典主义——平凡之美 佳作欣赏(摄影,欣赏)
文中图片摘自腾讯文化网:www.cal.qq.com 1.Abstract 生活本就是平淡的,如同真理一般寂静.平时生活中不经意的瞬间,也有它本来的美丽.下面一组图是上上个世纪到上个世纪末一个 ...
- centos 搭建ftp服务器
1.安装vsftpd sudo yum install vsftpd 2.配置vsftpd.conf # Allow anonymous FTP? (Beware - allowed by defau ...
- 设计模式之美:Null Object(空对象)
索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Null Object 的示例实现. 意图 通过对缺失对象的封装,以提供默认无任何行为的对象替代品. Encapsulate t ...
- 《你必须知道的.NET》读书笔记二:小OO有大原则
此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.单一职责原则 (1)核心思想:一个类最好只做一件事,只有一个引起它变化的原因 (2)常用模式:Fa ...
- question
1.软件工程技术和软件应用技术用什么区别吗? 2.软件工程专业和计算机技术(不是计算机科学与技术)有什么区别吗? 3.
- 【读书笔记】Ninject 在MVC5中的使用
从MVC3中就开始接触Ninject这个IOC工具.也一直是MVC Framework系列书籍中推荐的IOC工具,当然还有优秀的Autofac等.性能和使用上面个有千秋.下面先看一下Ninject的使 ...
- Nim编码风格
介绍 Nim语言不限制开发人员使用哪种具体的编码风格, 但为了社区的发展,在编写一些标准库的时候还是应该遵从统一的编码风格 这篇文章会列出一系列的编码风格准则,供大家参考. 但值得注意的是,有很多例外 ...
- FusionCharts简单教程(三)-----FusionCharts的基本属性
通过前面两章的讲解我们可以制作出简单的图像,但是有时候我们需要对图像进行一个精确的规划,比如设置背景颜色.设置提示信息.设置间隔颜色等等,这时就需要我们对FusionCharts的细节有比 ...