bzoj 2938 病毒 AC自动机
2017-04-13 18:42
239 查看
在补全之后的AC自动机上顺着child找环而不经过终止节点,如果存在环,则说明我们可以顺着这条路径构造无限长的字符串。
#include<queue> #include<cstdio> #include<cstring> #include<iostream> #define maxn 100005 using namespace std; char s[maxn]; struct Trie{ bool val[maxn]; int fail[maxn]; int ch[maxn][2],cnt; void insert() { int p=0; int n=strlen(s+1); for(int i=1;i<=n;i++) { int c=s[i]-'0'; if(!ch[p][c]) ch[p][c]=++cnt; p=ch[p][c]; } val[p]=1; } queue<int> Q; void build() { for(int i=0;i<=1;i++) if(ch[0][i]) Q.push(ch[0][i]); while(!Q.empty()) { int r=Q.front();Q.pop(); for(int i=0;i<=1;i++) { int u=ch[r][i]; if(!u) { ch[r][i]=ch[fail[r]][i]; continue; } Q.push(u); int p=fail[r]; while(p&&!ch[p][i]) p=fail[p]; fail[u]=ch[p][i]; val[u]|=val[fail[u]]; } } } bool ins[maxn]; bool vis[maxn]; bool dfs(int x) { bool can=0; ins[x]=vis[x]=1; for(int i=0;i<=1;i++) { int v=ch[x][i]; if(!val[v]) { if(vis[v])return true; if(!ins[v]&&dfs(v))return true; } } vis[x]=0; return false; } }AC; int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%s",s+1); AC.insert(); } AC.build(); if(AC.dfs(0)) puts("TAK"); else puts("NIE"); return 0; }
相关文章推荐
- [bzoj2938][Poi2000]病毒 AC自动机
- 【bzoj2938】[Poi2000]病毒 AC自动机
- 【bzoj2938】[Poi2000]病毒 AC自动机
- 【BZOJ2938】病毒,AC自动机练习
- BZOJ 2938: [Poi2000]病毒 AC自动机
- BZOJ 2938: [Poi2000]病毒 AC自动机
- BZOJ 2938 [Poi2000]病毒(AC自动机)
- BZOJ_2938_[Poi2000]病毒_AC自动机
- 【AC自动机】【bzoj 2938】: [Poi2000]病毒
- bzoj 2938: [Poi2000]病毒(AC自动机)
- BZOJ2938 POI2000 病毒 补全AC自动机 Trie图判环
- [bzoj2938][Poi2000]病毒_AC自动机
- 【bzoj 2938】病毒(AC自动机)
- [BZOJ]2938 [POI2000] 病毒 AC自动机
- 【bzoj2938】病毒 AC自动机
- BZOJ 2938: [Poi2000]病毒 [AC自动机 拓扑排序]
- AC自动机【poi2000】bzoj2938 病毒
- bzoj2938 [Poi2000]病毒 ac自动机
- bzoj 2938: [Poi2000]病毒 AC自动机
- 病毒(bzoj 2938)