• 【洛谷P2444】【POI2000】—病毒(Ac自动机)


    传送门

    很显然就是从AcAc自动机根开始走不经过任何一个终点有一个环

    记得建failfail的时候下传终点标记

    #include<bits/stdc++.h>
    using namespace std;
    const int RLEN=1<<20|1;
    inline char gc(){
        static char ibuf[RLEN],*ib,*ob;
        (ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
        return (ob==ib)?EOF:*ib++;
    }
    #define gc getchar
    inline int read(){
        char ch=gc();
        int res=0,f=1;
        while(!isdigit(ch))f^=ch=='-',ch=gc();
        while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
        return f?res:-res;
    }
    #define ll long long
    #define re register
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    #define cs const
    #define bg begin
    #define poly vector<int>
    #define chemx(a,b) ((a)<(b)?(a)=(b):0)
    #define chemn(a,b) ((a)>(b)?(a)=(b):0)
    cs int N=30005;
    namespace Ac{
    	int nxt[N][2],fail[N],vis[N],vt[N],tot,ed[N];
    	inline void insert(char *s){
    		int p=0;
    		for(int i=1,len=strlen(s+1);i<=len;i++){
    			int c=s[i]-'0';
    			if(!nxt[p][c])nxt[p][c]=++tot;
    			p=nxt[p][c];
    		}
    		ed[p]=1;
    	}
    	queue<int> q;
    	inline void buildfail(){
    		for(int i=0;i<=1;i++){
    			if(nxt[0][i])q.push(nxt[0][i]);
    		}
    		while(!q.empty()){
    			int p=q.front();q.pop();
    			for(int c=0;c<=1;c++){
    				int v=nxt[p][c];
    				if(v)fail[v]=nxt[fail[p]][c],q.push(v),ed[v]|=ed[fail[v]];
    				else nxt[p][c]=nxt[fail[p]][c];
    			}
    		}
    	}
    	bool dfs(int u){
    		vis[u]=vt[u]=1;
    		bool res=0;
    		for(int i=0;i<=1;i++){
    			int v=nxt[u][i];
    			if(ed[v])continue;
    			if(vis[v])return true;
    			if(vt[v])continue;
    			if(dfs(v))return true;
    		}
    		vis[u]=0;
    		return false;
    	}
    	inline bool findloop(){
    		return dfs(0);
    	}
    }
    int n;
    char s[2005];
    int main(){
    	n=read();
    	for(int i=1;i<=n;i++){
    		scanf("%s",s+1);
    		Ac::insert(s);
    	}
    	Ac::buildfail();
    	if(Ac::findloop())cout<<"TAK
    ";
    	else cout<<"NIE
    ";
    }
    
  • 相关阅读:
    比较全的屏幕信息
    使用div实现progress进度条
    选项卡效果的菜单栏
    javascript写的轮播图
    centos6.5 命令行配置无线上网
    CentOS 6.5 BCM43142 80211无线网卡驱动安装
    [数据库] windows server 2003下mysql出现10048错误的解决办法 Can't connect to MySQL server on '127.0.0.1' (10048)
    桥接模式-多台虚拟机配置(重要)
    VMware虚拟机中如何配置静态IP
    MySQL5.7 mysql.user创建用户
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328458.html
Copyright © 2020-2023  润新知