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

    Description

    二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码。如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的。现在委员会已经找出了所有的病毒代码段,试问,是否存在一个无限长的安全的二进制代码。

    示例: 例如如果{011, 11, 00000}为病毒代码段,那么一个可能的无限长安全代码就是010101…。如果{01, 11, 000000}为病毒代码段,那么就不存在一个无限长的安全代码。 任务: 请写一个程序: (1) 读入病毒代码;

    (2) 判断是否存在一个无限长的安全代码;

    (3) 将结果输出

    Input Format

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

    Output Format

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

    Solution

    建AC自动机,将fail指针合并到子节点上,然后形成一个有向图,

    然后在图上dfs,如果有环就是有无限长的串

    Code

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #define N 30010
    using namespace std;
    
    char s[N];
    int n,T[N][2],fail[N],cnt=1,q[N];
    bool mark[N],vis[N],inq[N];
    
    inline void Insert(){
    	scanf("%s
    ",s);
    	int len=strlen(s),now=1;
    	for(int i=0;i<len;++i){
    		if(!T[now][s[i]-'0']) T[now][s[i]-'0']=++cnt;
    		now=T[now][s[i]-'0'];
    	}
    	mark[now]=1;
    }
    
    inline void getfail(){
    	int h=0,t=0,now;q[++t]=1;
    	for(int i=0;i<2;++i) T[0][i]=1;
    	while(h<t){
    		now=q[++h];
    		for(int i=0;i<2;++i)			
    			if(T[now][i]){
    				int k=fail[now];
    				while(!T[k][i]) k=fail[k];
    				fail[q[++t]=T[now][i]]=T[k][i];
    				mark[T[now][i]]|=mark[T[k][i]];
    			}else T[now][i]=T[fail[now]][i];	
    	}
    }
    
    bool dfs(int u){
    	inq[u]=1;
    	for(int i=0;i<2;++i){
    		int v=T[u][i];
    		if(inq[v]) return 1;
    		if(vis[v]||mark[v]) continue;
    		vis[v]=1;
    		if(dfs(v)) return 1;
    	}
    	inq[u]=0;
    	return 0;
    }
    
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i) Insert();
    	getfail();
    	dfs(1)?puts("TAK"):puts("NIE");
    	return 0;
    }
    
  • 相关阅读:
    nginx能访问html静态文件但无法访问php文件
    LeetCode "498. Diagonal Traverse"
    LeetCode "Teemo Attacking"
    LeetCode "501. Find Mode in Binary Search Tree"
    LeetCode "483. Smallest Good Base" !!
    LeetCode "467. Unique Substrings in Wraparound String" !!
    LeetCode "437. Path Sum III"
    LeetCode "454. 4Sum II"
    LeetCode "445. Add Two Numbers II"
    LeetCode "486. Predict the Winner" !!
  • 原文地址:https://www.cnblogs.com/void-f/p/9016508.html
Copyright © 2011-2022 走看看