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

    传送门:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2938

    思路:构建AC自动机,无限长的安全代码就是能一直在AC自动机上匹配而匹配不上任何一个危险串。依旧是匹配指针不能走到危险串的结尾点x,fail指针指向x的y也不能走,因为根据fail的定义,x这个危险串是y的后缀。找出危险节点后就是找环了,有环就有无限长的安全代码,否则没有。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    const int maxn=30010;
    using namespace std;
    int n;char s[maxn];
    
    struct AC_DFA{
    	int tot,ch[maxn][2],fail[maxn],q[maxn],head,tail;bool dang[maxn],bo[maxn],ins[maxn];
    	void insert(){
    		int p=0;
    		for (int i=0;i<(int)strlen(s);p=ch[p][s[i]-'0'],i++) if (!ch[p][s[i]-'0']) ch[p][s[i]-'0']=++tot;
    		dang[p]=1;
    	}
    	void getfail(){
    		head=0,q[tail=1]=0,fail[0]=-1;
    		while (head!=tail){
    			int x=q[++head];
    			for (int i=0;i<=1;i++)
    				if (ch[x][i])
    					q[++tail]=ch[x][i],fail[ch[x][i]]=x==0?0:ch[fail[x]][i],dang[ch[x][i]]|=dang[fail[ch[x][i]]];
    				else ch[x][i]=x==0?0:ch[fail[x]][i];
    		}
    	}
    	bool dfs(int x){
    		ins[x]=1;
    		for (int i=0;i<=1;i++){
    			int v=ch[x][i];
    			if (ins[v]) return 1;
    			if (bo[v]||dang[v]) continue;
    			bo[v]=1;
    			if (dfs(v)) return 1;
    		}
    		ins[x]=0;return 0;
    	}
    }T;
    
    int main(){
    	scanf("%d",&n);
    	for (int i=1;i<=n;i++) scanf("%s",s),T.insert();
    	T.getfail(),puts(T.dfs(0)?"TAK":"NIE");
    	return 0;
    }


  • 相关阅读:
    个人总结11
    进度条4,5
    对vivo自带输入法的评价
    个人总结10
    hdu5589Tree
    HDU5213 Lucky
    2018icpcShenYangE
    bzoj3683: Falsita
    cf396C. On Changing Tree
    cf600E. Lomsat gelral
  • 原文地址:https://www.cnblogs.com/thythy/p/5493566.html
Copyright © 2011-2022 走看看