BZOJ2938 POI2000 病毒 题解&代码
2016-03-11 16:45
330 查看
题意:给出n个病毒代码,判断是否有无限长度的代码满足:不包含任何病毒代码。
题解:
看到多字符串匹配,就想到AC自动机【这语气好奇怪
AC自动机建好fail指针,然后从根向下dfs查找,所有实节点都用flag标记,如果找到了一个不经过病毒路径的环,那么就存在无限长度代码满足不包含任何病毒代码
题解:
看到多字符串匹配,就想到AC自动机【这语气好奇怪
AC自动机建好fail指针,然后从根向下dfs查找,所有实节点都用flag标记,如果找到了一个不经过病毒路径的环,那么就存在无限长度代码满足不包含任何病毒代码
/************************************************************** Problem: 2938 User: Rainbow6174 Language: C++ Result: Accepted Time:52 ms Memory:2128 kb ****************************************************************/ #include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn = 30005; int n, tot, ch[maxn][2], fail[maxn], danger[maxn], q[maxn], flag, temp, vis[maxn], e[maxn]; char s[maxn]; void addtrie(char s[]) { int x = 0, p = 0, len = strlen(s); while( p < len ) { temp = s[p]-'0'; if( !ch[x][temp] ) ch[x][temp]=++tot; x = ch[x][temp]; p++; } danger[x] = 1; } void AC(void) { int h = 0, t = 0; for(int i = 0; i < 2; i++) if(ch[0][i]) q[t++] = ch[0][i]; while( h < t ) { temp = q[h++]; for(int i = 0; i < 2; i++) { if(!ch[temp][i]) ch[temp][i] = ch[fail[temp]][i]; else { fail[ch[temp][i]] = ch[fail[temp]][i]; danger[ch[temp][i]] |= danger[ch[fail[temp]][i]]; q[t++] = ch[temp][i]; } } } } void dfs(int x) { if(flag) return; if(x) vis[x] = 1; for(int i = 0; i < 2; i++) { int v = ch[x][i]; if(vis[v]) { flag = 1; return; } if(e[v] || danger[v])continue; e[v] = 1; dfs(v); } vis[x] = 0; } int main(void) { scanf("%d", &n); for(int i = 0; i < n; i++) { scanf("%s", s); addtrie(s); } AC(); dfs(0); if(flag) printf("TAK\n"); else printf("NIE\n"); return 0; }
相关文章推荐
- php提示undefined index的几种解决方法
- python常用的备份脚本
- MATLAB数据降维工具箱drtoolbox介绍
- 使用java反射机制对类字段进行选择性校验示例
- PHP无限分类-左右值实现
- ansible-python自动化运维框架实例
- C# 中split的用法
- C语言二维数组与指针
- Java_移位运算
- Java常用类库--观察者设计模式( Observable类Observer接口)
- Matlab 处理时间加减问题
- 二叉树之-OC语言实现
- python json
- php生成图片验证码
- 红外与可见光图像配准算法--MATLAB版
- C语言基础02
- Java 获取类名,函数名,行数
- 2016年c#初使用
- 小记C++中+=与++的区别
- Struts2模型驱动核心机制详解