bzoj2938 [POI2000]病毒(ACAM+拓扑序判环)
2018-03-23 10:34
411 查看
问是否存在一个无限长的串不包含任意模式串。
那么我们建出ACAM,删去所有不能走的点(即模式串结尾),看是否存在一个环,如果存在则可以。可以用拓扑序来判环。
那么我们建出ACAM,删去所有不能走的点(即模式串结尾),看是否存在一个环,如果存在则可以。可以用拓扑序来判环。
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; #define ll long long #define N 30010 #define inf 0x3f3f3f3f inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f; } int n=0,nn,son [2],fail ,rt,tot=0,ans=0,in ; bool ed ; char s ;queue<int>q; inline void ins(char *s){ int len=strlen(s+1),p=rt; for(int i=1;i<=len;++i){ int &y=son[p][s[i]-'0'];if(!y) y=++n;p=y; }ed[p]=1; } inline void buildAC(){ q.push(rt); while(!q.empty()){ int x=q.front();q.pop(); for(int i=0;i<2;++i){ int &y=son[x][i]; if(!y){y=son[fail[x]][i];continue;}q.push(y); fail[y]=son[fail[x]][i];ed[y]|=ed[fail[y]]; } } } int main(){ // freopen("a.in","r",stdin); nn=read();rt=++n;son[0][0]=son[0][1]=rt; while(nn--) scanf("%s",s+1),ins(s);buildAC(); for(int i=1;i<=n;++i){ if(ed[i]) continue;++tot; for(int j=0;j<2;++j) if(!ed[son[i][j]]) in[son[i][j]]++; }for(int i=1;i<=n;++i) if(!ed[i]&&!in[i]) q.push(i),++ans; while(!q.empty()){ int x=q.front();q.pop(); for(int i=0;i<2;++i){ int y=son[x][i];if(ed[y]) continue; if(--in[y]==0) q.push(y),++ans; } }puts(ans==tot?"NIE":"TAK"); return 0; }
相关文章推荐
- BZOJ2938 POI2000 病毒 补全AC自动机 Trie图判环
- BZOJ_2938_[Poi2000]病毒_AC自动机
- 【bzoj2938】[Poi2000]病毒 trie图+dfs
- bzoj2938 [Poi2000]病毒
- [bzoj2938][Poi2000]病毒_AC自动机
- [bzoj2938] [Poi2000]病毒
- BZOJ 2938 Poi2000 病毒 AC自动机+拓扑排序
- bzoj 2938 [Poi2000]病毒
- BZOJ 2938 [Poi2000]病毒
- bzoj2938 [Poi2000]病毒 ac自动机
- BZOJ 2938 [Poi2000]病毒
- [bzoj2938][Poi2000]病毒
- [BZOJ2938][POI2000]病毒(AC自动机+dfs)
- [BZOJ 2938][Poi2000]病毒
- [bzoj2938][Poi2000]病毒 AC自动机
- [BZOJ2938][POI2000]病毒 做题笔记
- bzoj2938 [Poi2000]病毒
- BZOJ 2938 [Poi2000]病毒(AC自动机)
- 【bzoj2938】[Poi2000]病毒
- 【BZOJ】【2938】【POI2000】病毒