/*
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自动机的更多相关文章

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

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

  2. hdu 2896 病毒侵袭 AC自动机 基础题

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

  3. HDU 2896 病毒侵袭 (AC自己主动机)

    pid=2896">http://acm.hdu.edu.cn/showproblem.php?pid=2896 病毒侵袭 Time Limit: 2000/1000 MS (Java ...

  4. hdu 2896 病毒侵袭_ac自动机

    题意:略 思路:套用ac自动机模板 #include <iostream> #include<cstdio> #include<cstring> using nam ...

  5. HDU 2896 病毒侵袭 AC自己主动机题解

    本题是在text里面查找key word的增强版.由于这里有多个text. 那么就不能够简单把Trie的叶子标志记录改动成-1进行加速了,能够使用其它技术.我直接使用个vis数组记录已经訪问过的节点, ...

  6. HDU 2896 病毒侵袭(AC自动机水)

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

  7. HDU 2896 病毒侵袭(AC自动机)

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

  8. HDU 2896 病毒侵袭【AC自动机】

    <题目链接> Problem Description 当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻....在这样的时刻,人们却异常兴奋——我们能在有生之年看到500年一 ...

  9. hdu2896 病毒侵袭 ac自动机

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=2896 题目: 病毒侵袭 Time Limit: 2000/1000 MS (Java/Othe ...

随机推荐

  1. 基于VC的ACM音频编程接口压缩Wave音频(三)

    (三)音 频 数 据 的 压 缩 下 面 说 明 使 用 CODEC 实 现 音 频 压 缩 的 过 程:假 设 源 信 号 为8K 采 样.16bits PCM 编 码. 单 声 道. 长 度 为1 ...

  2. oracle 读书笔记

    1 动态sql即拼接字符串的sql,使用变量代替具体值,10万条语句可以被hash陈一个SQL_ID,可以只解析一次 for i in 1..100000 loop execute immediate ...

  3. Android 把电话保存到现有联系人 已有联系人

    搜索了很长时间,想找个把电话保存到现有联系人的代码,就是打开选中的联系人编辑界面,然后自动添加电话,再手动保存,就跟手机上的一样,功夫不负有心人,终于给搜到了,很不容易啊,现分享如下, // 保存至现 ...

  4. WEB开发之路——基础部分

    WEB开发之路 受BBC的<BBC: Brain Story>和<BBC: The Brain - A Secret History>的影响,我一直有志于探究人类大脑,2015 ...

  5. 在浏览器的JavaScript里new Date().toUTCString()后,传递给C# DateTime().TryParse()会发生什么?

    Format 1. Sun, 09 Oct 2016 13:24:35 GMT Format 2. Sun, 9 Oct 2016 13:36:09 UTC Format 1 是在IE里面产生的(Wi ...

  6. 学习Word2vec

    有感于最近接触到的一些关于深度学习的知识,遂打算找个东西来加深理解.首选的就是以前有过接触,且火爆程度非同一般的word2vec.严格来说,word2vec的三层模型还不能算是完整意义上的深度学习,本 ...

  7. 一种基于Orleans的分布式Id生成方案

    基于Orleans的分布式Id生成方案,因Orleans的单实例.单线程模型,让这种实现变的简单,贴出一种实现,欢迎大家提出意见 public interface ISequenceNoGenerat ...

  8. 用JQuery仿造QQ头像裁剪功能

    最近工作真心忙碌,几乎没时间写博客.今天趁周末来仿一个QQ头像裁剪功能插件.效果如下: 所有文件都可在我的Github上下载,从头到尾从简到繁按步骤一共分了9个HTML文件,每个步骤文件里的注释都写的 ...

  9. 新手的第一个phonegap Android应用

    对PhoneGap开发感兴趣的请加入群 PhoneGap App开发 348192525   手机成为现在软件应用必不可少的一种设备,然而手机平台的不统一造成我们需要为不同手机重写代码,这对一般应用来 ...

  10. 简介Gulp, Grunt, Bower, 和 Npm 对Visual Studio的支持

    [原文发表地址]Introducing Gulp, Grunt, Bower, and npm support for Visual Studio Web 开发,特别是前端 Web 开发,正迅速变得像 ...