zoukankan      html  css  js  c++  java
  • [POI2000]病毒(AC自动机)

    题意

    给定一些字符串,问是否存在一个无限长度的字符串,使得它不包含任何一个给定的串

    思路

    将所有串加入AC自动机,那么我们从根节点选择的一个字符串显然不能经过任何一个带有end标记的节点,不然就说明其中包含了这个节点对应的字符串。

    于是用fail标记建成trie图,判断trie图上面有没有一个不经过end标记的环即可

    Code:

    #include<bits/stdc++.h>
    #define N 30005
    using namespace std;
    int n;
    int nxt[N][2],fail[N],ndsum;
    char c[N];
    bool is_end[N],vis[N],st[N];
    
    void ad(char a[])
    {
        int l=strlen(a),now=0;
        for(int i=0;i<l;++i)
        {
            int pp=a[i]-'0';
            if(!nxt[now][pp]) nxt[now][pp]=++ndsum;
            now=nxt[now][pp];
        }
        is_end[now]=1;
    }
    void getfail()
    {		
        queue<int> q;
        for(int i=0;i<2;++i) if(nxt[0][i]) q.push(nxt[0][i]);
        while(!q.empty())
        {
            int u=q.front();q.pop();
            for(int i=0;i<2;++i)
            if(nxt[u][i]) fail[nxt[u][i]]=nxt[fail[u]][i],q.push(nxt[u][i]),is_end[nxt[u][i]]|=is_end[fail[nxt[u][i]]];
            else nxt[u][i]=nxt[fail[u]][i];
        }
    }
    bool dfs(int u)
    {
        if(st[u]) return true;
        if(vis[u]) return false;
        vis[u]=st[u]=1;
        for(int i=0;i<2;++i)
        {
            if(nxt[u][i]&&!is_end[nxt[u][i]]) if(dfs(nxt[u][i])) return true;
        }
        st[u]=0;
        return false;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
        {
            scanf("%s",c);
            ad(c);
        }
        getfail();
        memset(vis,0,sizeof(vis));
        if(dfs(0)) printf("TAK
    ");
        else printf("NIE
    ");
        return 0;
    }
    
  • 相关阅读:
    jmeter 插件
    jmeter beanshell
    Linux awk&sed
    Linux 各文件系统配置
    Linux常用基本命令 1
    testNg自动化,读取excel的数据
    jmeter 控制器
    Web
    SQL语句
    HTML
  • 原文地址:https://www.cnblogs.com/Chtholly/p/11185755.html
Copyright © 2011-2022 走看看