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

思路分析:题目为模式匹配问题,对于一个给定的字符串,判断能匹配多少个模式;该问题需要静态建树,另外需要对AC自动机的模板加以修改,

对于每个匹配的模式的最后一个单词的fail指针指向root,即可实现一个字符串进行多次模式匹配;

代码如下:

  1. #include <queue>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <iostream>
  5. #include <algorithm>
  6. using namespace std;
  7.  
  8. const int KIND = ;
  9. const int MAX_NODE = * ;
  10. const int MAX_M = + ;
  11. char str[MAX_M];
  12. int vir_match[MAX_M];
  13.  
  14. struct Trie {
  15. int root, count;
  16. int next[MAX_NODE][KIND], fail[MAX_NODE], end[MAX_NODE];
  17. void Init()
  18. {
  19. count = ;
  20. root = NewNode();
  21. }
  22. int NewNode()
  23. {
  24. for (int i = ; i < KIND; ++i)
  25. next[count][i] = -;
  26. end[count] = -;
  27. return count++;
  28. }
  29.  
  30. void Insert(char *str, int id)
  31. {
  32. int i = , k = ;
  33. int now = root;
  34.  
  35. while (str[i])
  36. {
  37. k = str[i];
  38. if (next[now][k] == -)
  39. next[now][k] = NewNode();
  40. now = next[now][k];
  41. ++i;
  42. }
  43. end[now] = id;
  44. }
  45.  
  46. void BuildAutomaton()
  47. {
  48. queue<int> Q;
  49.  
  50. fail[root] = -;
  51. Q.push(root);
  52. while (!Q.empty())
  53. {
  54. int now = Q.front();
  55. int p = -;
  56. Q.pop();
  57.  
  58. if (end[now] != -)
  59. fail[now] = root;
  60. for (int i = ; i < KIND; ++i)
  61. {
  62. if (next[now][i] != -)
  63. {
  64. if (now == root)
  65. fail[next[now][i]] = root;
  66. else
  67. {
  68. p = fail[now];
  69. while (p != -)
  70. {
  71. if (next[p][i] != -)
  72. {
  73. fail[next[now][i]] = next[p][i];
  74. break;
  75. }
  76. p = fail[p];
  77. }
  78. if (p == -)
  79. fail[next[now][i]] = root;
  80. }
  81. Q.push(next[now][i]);
  82. }
  83. }
  84. }
  85. }
  86.  
  87. int Match(char *str)
  88. {
  89. int i = , k = , vir_count = ;
  90. int p = root;
  91.  
  92. while (str[i])
  93. {
  94. k = str[i];
  95. while (next[p][k] == - && p != root)
  96. p = fail[p];
  97. p = next[p][k];
  98. p = (p == -) ? root : p;
  99.  
  100. if (end[p] != -)
  101. {
  102. vir_match[vir_count++] = end[p];
  103. p = fail[p];
  104. }
  105. ++i;
  106. }
  107. return vir_count;
  108. }
  109. };
  110.  
  111. Trie root;
  112.  
  113. int main()
  114. {
  115. int vir_num = , web_num = ;
  116. int match_count = , web_matched = ;
  117.  
  118. while (scanf("%d\n", &vir_num) != EOF)
  119. {
  120. root.Init();
  121. for (int i = ; i < vir_num; ++i)
  122. {
  123. gets(str);
  124. root.Insert(str, i + );
  125. }
  126.  
  127. web_matched = ;
  128. match_count = ;
  129. root.BuildAutomaton();
  130. scanf("%d\n", &web_num);
  131. for (int i = ; i < web_num; ++i)
  132. {
  133. int ans = ;
  134.  
  135. gets(str);
  136. ans = root.Match(str);
  137. sort(vir_match, vir_match + ans);
  138. if (ans)
  139. {
  140. web_matched++;
  141. printf("web %d: ", i + );
  142. for (int j = ; j < ans - ; ++j)
  143. printf("%d ", vir_match[j]);
  144. printf("%d\n", vir_match[ans - ]);
  145. }
  146. }
  147. printf("total: %d\n", web_matched);
  148. }
  149. return ;
  150. }

hdoj 2896 病毒侵袭(AC自动机)的更多相关文章

  1. hdu 2896 病毒侵袭 ac自动机

    /* hdu 2896 病毒侵袭 ac自动机 从题意得知,模式串中没有重复的串出现,所以结构体中可以将last[](后缀链接)数组去掉 last[]数组主要是记录具有相同后缀模式串的末尾节点编号 .本 ...

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

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

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

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

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

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

  5. hdu2896 病毒侵袭 ac自动机

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

  6. hdu2896 病毒侵袭 AC自动机入门题 N(N <= 500)个长度不大于200的模式串(保证所有的模式串都不相同), M(M <= 1000)个长度不大于10000的待匹配串,问待匹配串中有哪几个模式串,

    /** 题目:hdu2896 病毒侵袭 链接:http://acm.hdu.edu.cn/showproblem.php?pid=2896 题意:N(N <= 500)个长度不大于200的模式串 ...

  7. 【HDU2896】病毒侵袭 AC自动机

    [HDU2896]病毒侵袭 Problem Description 当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻....在这样的时刻,人们却异常兴奋--我们能在有生之年看到500年 ...

  8. HDu-2896 病毒侵袭,AC自动机模板题!

    病毒侵袭 模板题,不多说了.. 题意:n个不同的字符串分别代表病毒特征,给出m次查询,每次一个字符串(网址),求这个字符串中有几个病毒特征,分别从大到小输出编号,最后输出所有的带病毒网址个数.格式请看 ...

  9. hduoj-----(2896)病毒侵袭(ac自动机)

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

随机推荐

  1. pushViewController自定义动画

    实现的主要代码如下: CATransition *transition = [CATransition animation]; transition.duration = 1.0f; transiti ...

  2. 堆分配与栈分配---SAP C++电面(5)/FEI

    一直以来总是对这个问题的认识比较朦胧,我相信很多朋友也是这样的,总是听到内存一会在栈上分配,一会又在堆上分配,那么它们之间到底是怎么的区别呢?为了说明这个问题,我们先来看一下内存内部的组织情况. 从上 ...

  3. IT工程师值得一看的书籍

    http://blog.csdn.net/chinahuyong/article/details/45060203

  4. hadoop hdfs 一些命令记录

    1.列出目录下的对象:hadoop fs -ls /lib 2.统计文件行数:hadoop fs -cat  /文件* | wc -l 3.统计文件或者目录大小:hadoop fs -count /l ...

  5. jQuery实时获取checkbox状态问题

    在最近的项目开发中,使用jQuery操作checkbox时,发现一个问题. Html代码如下: <body> <div> <inputtype="checkbo ...

  6. Use eplipse to develop Python project

    Source: This is the example how to use eclipse and python. http://www.360doc.com/content/15/0206/10/ ...

  7. Android 5.x新特性之elevation(阴影),tinting(着色)以及clipping(剪裁)

    快过年了,公司也没事做了, 自己也闲了下来,一天天呆着真没意思,闲来没事自己研究研究了Google I/O 2014 发布 Material Design设计,人性化的风格,丰富的色彩,使人机交互更完 ...

  8. 使用LAMP创建基于wordpress的个从博客站点

    參考: http://blog.csdn.net/ck_boss/article/details/27866117 一.mysql配置 1.安装mysql yum install mysql-serv ...

  9. 【Oracle】RAC添加新节点

    RAC添加节点: 环境: OS:OEL5.6 RAC:10.2.0.1.0 原有rac1,rac2两个节点.如今要添加rac3节点: 操作过程: 改动三个节点上的/etc/hosts文件 192.16 ...

  10. Apache OFbiz entity engine源代码解读

    简单介绍 近期一直在看Apache OFbiz entity engine的源代码.为了能够更透彻得理解,也由于之前没有看人别人写过分析它的文章,所以决定自己来写一篇. 首先,我提出一个问题,假设你有 ...