zoukankan      html  css  js  c++  java
  • BZOJ2938: [Poi2000]病毒

    【传送门:BZOJ2938


    简要题意:

      给出n个01串,判断是否存在一个无限长的01串不包含任意一个给出的01串


    题解:

      AC自动机构造fail指针,画一下图可以知道

      如果在字典树中找到环,就可以找到一个无限长的01串

      注意:当一个点有一个儿子不存在时,可以将fail边当作儿子边来使用,这样子就可以直接dfs找环了


    参考代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    using namespace std;
    struct trie
    {
        int c[2],s,fail;
        trie()
        {
            s=0;fail=0;
            c[0]=c[1]=-1;
        }
    }t[31000];int tot;
    char st[31000];
    void bt()
    {
        int len=strlen(st+1),x=0;
        for(int i=1;i<=len;i++)
        {
            int y=st[i]-'0';
            if(t[x].c[y]==-1) t[x].c[y]=++tot;
            x=t[x].c[y];
        }
        t[x].s=1;
    }
    queue<int> q;
    void bfs()
    {
        q.push(0);
        while(q.empty()==0)
        {
            int x=q.front();q.pop();
            for(int i=0;i<=1;i++)
            {
                int son=t[x].c[i];
                if(son==-1)
                {
                    t[x].c[i]=t[t[x].fail].c[i];
                    continue;
                }
                if(t[x].s==1) t[son].s=1;
                if(x==0) t[son].fail=0;
                else
                {
                    int j=t[x].fail;
                    while(j!=0&&t[j].c[i]==-1) j=t[j].fail;
                    t[son].fail=max(0,t[j].c[i]);
                    if(t[t[son].fail].s==1) t[son].s=1;
                }
                q.push(son);
            }
        }
    }
    bool v[31000],bo[31000];
    bool dfs(int x)
    {
        v[x]=true;bo[x]=true;
        for(int i=0;i<=1;i++)
        {
            int y=t[x].c[i];
            if(v[y]==true) return true;
            if(y==-1||t[y].s==1||bo[y]==true) continue;
            if(dfs(y)==true) return true;
        }
        v[x]=false;
        return false;
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",st+1);
            bt();
        }
        bfs();
        memset(bo,false,sizeof(bo));
        memset(v,false,sizeof(v));
        if(dfs(0)==true) printf("TAK
    ");
        else printf("NIE
    ");
        return 0;
    }

     

  • 相关阅读:
    《程序员修炼之道+从小工到专家》读后感2
    java在子类中,调用父类中被覆盖的方法
    长按文本全复制
    NSTimer 定时器总结
    对URL编码
    Mysql find_in_set 效率问题
    php 运算符优先级
    使用layui上传控件问题
    xcode11发版一直卡在App Store验证过不去
    iOS13禁用深色模式
  • 原文地址:https://www.cnblogs.com/Never-mind/p/9724531.html
Copyright © 2011-2022 走看看