刚学了ac自动机,去hzwer上找了道练习题;
串是安全的就说明ac自动机不会找到匹配,考虑ac自动机的匹配过程;
我们把val等于1的点删掉和fail指针指向被删掉的点删掉;
如果剩下的图有环,就有解;
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; const int maxn=30010; int tot,vis1[maxn],vis2[maxn],q[maxn],head,tail,in[maxn]; struct node{ int son[2],f,cnt,v; }ch[maxn]; char s[maxn]; void add(char s[]){ int u=0,len; len=strlen(s); for(int i=0;i<len;++i){ int c=s[i]-'0'; if(!ch[u].son[c]){ch[u].son[c]=++tot;} u=ch[u].son[c]; } ch[u].v=1; vis1[u]=1; } void pre(){ head=tail=0; ch[0].f=0; for(int i=0;i<2;++i){ if(ch[0].son[i])q[++tail]=ch[0].son[i]; } while(head<tail){ int now=q[++head]; for(int i=0;i<2;++i){ int u=ch[now].son[i]; if(!u){ch[now].son[i]=ch[ch[now].f].son[i];continue;} int v=ch[now].f; while(v&&!ch[v].son[i])v=ch[v].f; ch[u].f=ch[v].son[i]; vis1[u]|=vis1[ch[v].son[i]]; q[++tail]=u; } } } bool dfs(int x){ in[x]=1; for(int i=0;i<2;++i){ int v=ch[x].son[i]; if(in[v])return 1; if(vis1[v]||vis2[v])continue; vis2[v]=1; if(dfs(v))return 1; } in[x]=0; return 0; } int n; int main(){ scanf("%d",&n); for(int i=1;i<=n;++i){ scanf("%s",s); add(s); } pre(); if(dfs(0))puts("TAK"); else puts("NIE"); system("pause"); return 0; }