病毒侵袭 - HDU 2896(AC自动机)
2015-08-22 17:27
330 查看
分析:有点需要注意的,输入的字符是所有可见的ASCII码,刚开始没看清一直以为是小写字母.............注意到这点后这题就是裸的自动机了。
代码如下:
==============================================================================================
代码如下:
==============================================================================================
#include<stdio.h> #include<string.h> #include<algorithm> #include<queue> using namespace std; const int MAXN = 1e6+7; const int MAXM = 130; const int oo = 1e9+37; char webStr[MAXN], s[MAXN]; int ans[MAXN], top;///保存某个网站被那些病毒侵占了 struct node { node *Fali, *next[MAXM]; int leaf, nweb;///已经被第n个web匹配过了 }; void Insert(node *root, char s[], int num) { node *p = root; for(int i=0; s[i]; i++) { int k = (int)s[i]; if(p->next[k] == NULL) p->next[k] = new node(); p = p->next[k]; } p->leaf = num; } void GetFial(node *root) { node *p = root, *temp; queue<node *> Q; for(int i=0; i<MAXM; i++) if(p->next[i]) { p->next[i]->Fali = root; Q.push(p->next[i]); } while(Q.size()) { p = Q.front(); Q.pop(); for(int i=0; i<MAXM; i++)if(p->next[i]) { temp = p->Fali; while(temp != NULL) { if(temp->next[i] != NULL) { p->next[i]->Fali = temp->next[i]; break; } temp = temp->Fali; } if(temp == NULL) p->next[i]->Fali = root; Q.push(p->next[i]); } } } void FreeTrie(node *root) { node *p = root; for(int i=0; i<MAXM; i++) { if(p->next[i]) FreeTrie(p->next[i]); } free(p); } void Query(node *root, int nweb) { node *p = root, *temp; for(int i=0; webStr[i]; i++) { int k = (int)webStr[i]; while(!p->next[k] && p!=root) p = p->Fali; if(!p->next[k])continue; temp = p = p->next[k]; while(temp != root && temp->nweb != nweb) { if(temp->leaf) ans[top++] = temp->leaf; temp->nweb = nweb; } } } int main() { int i, N, M; while(scanf("%d", &N) != EOF) { node *root = new node(); for(i=1; i<=N; i++) { scanf("%s", s); Insert(root, s, i); } GetFial(root); scanf("%d", &M); int total = 0; for(i=1; i<=M; i++) { scanf("%s", webStr); top = 0; Query(root, i); if(top) { sort(ans, ans+top); printf("web %d:", i); for(int j=0; j<top; j++) printf(" %d", ans[j]); printf("\n"); total += 1; } } printf("total: %d\n", total); FreeTrie(root); } return 0; }
相关文章推荐
- 在一个字符串中找出以同样的顺序连续出现在另一个字符串中的最长连续字符串的长度
- POJ 3304 Segments(判断线段和直线是否相交)
- win7 访问ftp站点 不用浏览器显示
- 设计模式之责任链模式(2)
- stm32启动代码分析
- iOS高级-QuartzCore框架-图片裁剪
- Python第一天 - 迭代
- Win7搭建SVN server
- PISSTV 树莓派慢扫描电视
- php uploadify上传图片时url出现%EF%BB%BF
- 思聪女友开淘宝店净赚2亿,揭秘“网红工厂”吸金远超范冰冰
- 模拟 hdu5414 CRB and String
- 阿里题目总结——阿里巴巴2010搜索研发C++工程师笔试卷
- 再谈网游同步技术
- B. Random Teams(Codeforces Round 273)
- wince6.0 自己编译BSP 支持sqlCE3.0
- [leetcode]Remove Element C语言
- Android 6.0 新特性剖析【深度优化内存机制"秒杀"IOS系统】
- UVa:12545 Bits Equalizer(贪心)
- HDU2050 折线分割平面 (线段数学规律)