BZOJ2938 & 洛谷2444:[POI2000]病毒——题解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ2938 & 洛谷2444:[POI2000]病毒——题解相关的知识,希望对你有一定的参考价值。

http://www.lydsy.com/JudgeOnline/problem.php?id=2938

https://www.luogu.org/problemnew/show/P2444

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

对于多串,先建立AC自动机。

然后考虑对于没有病毒代码的代码来说,它会在AC自动机上一直走直到跳出。

而如果走出了一个环的话就意味着它可以沿着这个环无限延伸——这就是我们所要求的。

所以我们建立AC自动机跑dfs搜环(当然危险节点不能走),如果有环就是TAK,否则就是NIE。

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
const int N=2010;
const int M=30010;
struct trie{
    bool ed;
    int a[2],fail;
}tr[M*20];
int cnt=0;
char s[M];
inline void insert(){
    int now=0;
    int len=strlen(s);
    for(int i=0;i<len;i++){
        int t=s[i]-\'0\';
        if(!tr[now].a[t]){
            cnt++;
            tr[now].a[t]=cnt;
        }
        now=tr[now].a[t];
    }
    tr[now].ed=1;
    return;
}
void getfail(){
    queue<int>q;
    tr[0].fail=0;
    for(int i=0;i<2;i++){
        if(tr[0].a[i]){
            tr[tr[0].a[i]].fail=0;
            q.push(tr[0].a[i]);
        }
    }
    while(!q.empty()){
        int u=q.front();
        q.pop();
        for(int i=0;i<2;i++){
            if(tr[u].a[i]){
        int v=tr[u].a[i];
                tr[v].fail=tr[tr[u].fail].a[i];
        tr[v].ed|=tr[tr[v].fail].ed;
                q.push(tr[u].a[i]);
            }else{
                tr[u].a[i]=tr[tr[u].fail].a[i];
            }
        }
    }
    return;
}
bool vis[M*20],met[M*20];
bool dfs(int u){
    vis[u]=1;
    for(int i=0;i<2;i++){
    int v=tr[u].a[i];
    if(vis[v])return 1;
    if(tr[v].ed||met[v])continue;
    met[v]=1;
    if(dfs(v))return 1;
    }
    vis[u]=0;
    return 0;
}
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
    cin>>s;
    insert();
    }
    getfail();
    if(dfs(0))puts("TAK");
    else puts("NIE");
    return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

 +本文作者:luyouqi233。               +

 +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

以上是关于BZOJ2938 & 洛谷2444:[POI2000]病毒——题解的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 2938: [Poi2000]病毒

bzoj2938 病毒

BZOJ2938: [Poi2000]病毒

BZOJ3339:Rmq Problem & BZOJ3585 & 洛谷4137:mex——题解

bzoj2938

BZOJ1229 & 洛谷2917:[USACO2008 NOV]toy 玩具 & 洛谷4480:[BJWC2018]餐巾计划问题——题解

(c)2006-2024 SYSTEM All Rights Reserved IT常识