zoukankan      html  css  js  c++  java
  • BZOJ_2938_[Poi2000]病毒_AC自动机

    BZOJ_2938_[Poi2000]病毒_AC自动机

    Description

    二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码。如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的。现在委员会已经找出了所有的病毒代码段,试问,是否存在一个无限长的安全的二进制代码。
    示例:
    例如如果{011, 11, 00000}为病毒代码段,那么一个可能的无限长安全代码就是010101…。如果{01, 11, 000000}为病毒代码段,那么就不存在一个无限长的安全代码。
    任务:
    请写一个程序:
    l         读入病毒代码;
    l         判断是否存在一个无限长的安全代码;
    l         将结果输出

    Input

     
    第一行包括一个整数n,表示病毒代码段的数目。以下的n行每一行都包括一个非空的01字符串——就是一个病毒代码段。所有病毒代码段的总长度不超过30000。

    Output

    你应在在文本文件WIN.OUT的第一行输出一个单词:
    l         TAK——假如存在这样的代码;
    l         NIE——如果不存在。

    Sample Input

    3
    01
    11
    00000

    Sample Output

    NIE


    $trie$ 图真的是比$AC$ 自动机好写多了。

    存在这样的字符串,当且仅当在$trie$ 图上存在一个不包括病毒代码的环。

    具体操作:建个$trie$ 树,终止处打上标记,在建$fail$ 的时候把子树也标记上。

    代码:

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define N 2050
    #define M 60050
    char w[M];
    int ch[M][2],cnt[M],tot=1,n,Q[M],l,r,fail[M],vis[M],ins[M];
    void insert() {
        int p=1,i;
        for(i=0;w[i];i++) {
            int &k=ch[p][w[i]-'0'];
            if(!k) k=++tot;
            p=k;
        }
        cnt[p]=1;
    }
    void build() {
        int p,i;
        for(i=0;i<2;i++) ch[0][i]=1;
        Q[r++]=1;
        while(l<r) {
            p=Q[l++];
            for(i=0;i<2;i++) {
                if(ch[p][i]) fail[ch[p][i]]=ch[fail[p]][i],Q[r++]=ch[p][i];
                else ch[p][i]=ch[fail[p]][i];
                cnt[p]|=cnt[fail[p]];
            }
        }
    }
    bool dfs(int x) {
        vis[x]=1;
        ins[x]=1;
        int i,t;
        for(i=0;i<2;i++) {
            t=ch[x][i];
            if(ins[t]||(!vis[t]&&!cnt[t]&&dfs(t))) return 1;
        }
        ins[x]=0;
        return 0;
    }
    int main() {
        scanf("%d",&n);
        int i;
        for(i=1;i<=n;i++) {
            scanf("%s",w);
            insert();
        }
        build();
        puts(dfs(1)?"TAK":"NIE");
    }
    
  • 相关阅读:
    bzoj1415 NOI2005聪聪和可可
    Tyvj1952 Easy
    poj2096 Collecting Bugs
    COGS 1489玩纸牌
    COGS1487 麻球繁衍
    cf 261B.Maxim and Restaurant
    cf 223B.Two Strings
    cf 609E.Minimum spanning tree for each edge
    cf 187B.AlgoRace
    cf 760B.Frodo and pillows
  • 原文地址:https://www.cnblogs.com/suika/p/8891891.html
Copyright © 2011-2022 走看看