刚学了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;
}

 

posted on 2017-12-03 19:13  湮灭之瞳  阅读(169)  评论(0编辑  收藏  举报