• P2444 [POI2000]病毒


    传送门

    AC自动机

    如果有一个无限长的安全串

    那么这个串在所有危险代码构成的AC自动机上一直匹配下去都不会走到结束标记

    因为如果走到结束标记说明串中有危险代码

    考虑怎样才能无限匹配

    可以发现,如果在AC自动机上从根节点出发,一直走能走出一个环的话

    那么就可以一直走这个环,从而无限匹配下去

    所以要在自动机上找环

    可以用DFS实现

    有一点要注意

    不但有结尾标记的点不能走

    如果一个点一直走 fail 能走到一个有结束标记的点

    那么这个点也不能走

    因为这串的后面一部分会包含危险代码(AC自动机的性质)

    然后就是代码了

     

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int N=3e4+7;
    int n;
    int c[N][2],pd[N],fail[N],cnt;
    char a[N];
    inline void ins()//插入危险代码
    {
        int u=0,l=strlen(a);
        for(int i=0;i<l;i++)
        {
            int v=a[i]-'0';
            if(!c[u][v]) c[u][v]=++cnt;
            u=c[u][v];
        }
        pd[u]=1;
    }
    queue <int> q;
    inline void pre()//预处理fail以及不能走的点
    {
        for(int i=0;i<=1;i++) if(c[0][i]) q.push(c[0][i]);
        while(!q.empty())
        {
            int u=q.front(); q.pop();
            for(int i=0;i<=1;i++)
            {
                int v=c[u][i];
                if(!v) c[u][i]=c[fail[u]][i];
                else
                {
                    fail[v]=c[fail[u]][i];
                    if(pd[fail[v]]) pd[v]=1;
                    q.push(v);
                }
            }
        }
    }
    bool vis[N],p[N];//vis表示是否走过,p表示是否在当前路径上
    inline void dfs(int x)//dfs找环
    {
        if(p[x])//如果在当前路径上,说明找到环了
        {
            cout<<"TAK";
            exit(0);
        }
        if(vis[x]||pd[x]) return;
        vis[x]=p[x]=1;
        dfs(c[x][0]); dfs(c[x][1]);
        p[x]=0;
    }
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            scanf("%s",a);
            ins();
        }
        pre();
        dfs(0);
        cout<<"NIE";
        return 0;
    }
  • 相关阅读:
    C++11中静态局部变量初始化的线程安全性
    213. 打家劫舍 II
    cas解决aba相关问题
    socket[可读可写异常]3种条件的发生
    linux信号处理 (信号产生 信号阻塞 信号集)
    vim set paste解决粘贴乱序乱码问题
    174. 地下城游戏
    208. 实现 Trie (前缀树) 和 面试题 17.13. 恢复空格
    Centos安装和卸载docker
    Go语言轻量级框架-Gin与入门小案例MySQL增删查改
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/9682415.html
Copyright © 2020-2023  润新知