bzoj2938: [Poi2000]病毒
2018-07-12 21:27
537 查看
题目链接
bzoj2938: [Poi2000]病毒题解
简单的来说,就是构造一个只含0和1的字符串,不能与Trie完成匹配。dfs判一下trie图上是否存在与根节点相连没有串结尾的环
也就是有串结尾的点和fail指针指向串结尾的点,或指向不能走的点(也就是之前那一坨)的点也不能在环中
代码
#include<bits/stdc++.h> using namespace std; int n; const int maxn = 30007; char a[30007]; int ch[maxn][2],val[maxn]; int sz = 0; void Insert(char *s) { int len = strlen(s + 1),now = 0 ; for(int i = 1;i <= len;++ i) { int c = s[i] - '0'; if(!ch[now][c]) ch[now][c] = ++ sz; now = ch[now][c]; } val[now] = 1; } queue<int>q; int fail[maxn]; void getfail() { for(int i = 0;i <= 1;++ i) if(ch[0][i]) q.push(ch[0][i]); while(!q.empty() ) { int now = q.front(); q.pop(); for(int i = 0;i <= 1;++ i) { if(ch[now][i]) { fail[ch[now][i]] = ch[fail[now]][i]; val[ch[now][i]] |= val[ch[fail[now]][i]]; q.push(ch[now][i]); } else ch[now][i] = ch[fail[now]][i]; } } } bool vis[maxn],ht[maxn]; void dfs(int x) { vis[x] = 1; ht[x] = 1; for(int i =0;i <= 1;++ i) { int v = ch[x][i]; if(v) { if(vis[v]) { puts("TAK"); exit(0); } if(!ht[v] && !val[v]) dfs(v); } } vis[x] = 0; } int main() { scanf("%d",&n); for(int i = 1;i <= n;++ i) { scanf("%s",a + 1); Insert(a); } getfail(); dfs(0); puts("NIE"); return 0; }
相关文章推荐
- BZOJ2938 & 洛谷2444:[POI2000]病毒——题解
- BZOJ 2938: [Poi2000]病毒
- BZOJ 2938: [Poi2000]病毒 AC自动机
- BZOJ 2938: [Poi2000]病毒 AC自动机
- BZOJ 2938: [Poi2000]病毒 [AC自动机 拓扑排序]
- 【BZOJ】2938: [Poi2000]病毒
- bzoj 2938: [Poi2000]病毒 AC自动机
- bzoj 2938: [Poi2000]病毒
- BZOJ 2938: [Poi2000]病毒
- 【AC自动机】【bzoj 2938】: [Poi2000]病毒
- [BZOJ]2938 [POI2000] 病毒 AC自动机
- bzoj 2938: [Poi2000]病毒(AC自动机)
- 【BZOJ】【P2938】【Poi2000】【病毒】【题解】【AC自动机】
- [BZOJ2938][POI2000]病毒 做题笔记
- 【BZOJ】【2938】【POI2000】病毒
- bzoj千题计划260:bzoj2940: [Poi2000]条纹
- BZOJ2938: [Poi2000]病毒
- bzoj2946 [Poi2000]公共串(SA,SAM)
- [bzoj2938][Poi2000]病毒 AC自动机
- BZOJ 2946: [Poi2000]公共串