[POI2000]病毒(补全AC自动机)

题意

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

示例:

例如如果{011, 11, 00000}为病毒代码段,那么一个可能的无限长安全代码就是010101…。如果{01, 11, 000000}为病毒代码段,那么就不存在一个无限长的安全代码。

任务:

请写一个程序:

1.在文本文件WIR.IN中读入病毒代码;

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

3.将结果输出到文件WIR.OUT中。

输入格式:

在文本文件WIR.IN的第一行包括一个整数n(n\le 2000)(n2000),表示病毒代码段的数目。以下的n行每一行都包括一个非空的01字符串——就是一个病毒代码段。所有病毒代码段的总长度不超过30000。

输出格式:

在文本文件WIR.OUT的第一行输出一个单词:

TAK——假如存在这样的代码;

NIE——如果不存在。

题解

很容易想到将病毒串放入Trie树,补全后,如果能找到一个不经过任何串末尾的环就有一个安全代码

考虑如何找环,本来想的是拓扑排序,不过就算找出一个环,也很难判断是否含末尾点

然后又不小心听到了dfs,想了想很有道理,于是写出了如下东西

结果WA了一片,第一个样例就错了.....

那考虑为什么会这样,按照上面的写法,下个点访问过一定是环吗?

不一定,补全后就是一个有向图,所以我们拿有向图举例

如果先从1遍历完,然后回到1,再从2到1时,就会判断是环

然而不是,因为这是有向图,如果是无向图的话确实有环。

那么考虑怎么更正

在回溯时删除vis标记即可,这样能否找到环?

答案是确定的,因为会遍历到每个路径

#include<bits/stdc++.h>
using namespace std;

const int maxn=30005;
int n,num;
int go[maxn][2],fail[maxn]; 
char s[maxn];
bool end[maxn],vis[maxn];

void extend(int len){
    int now=0;
    for(int i=0;i<len;i++){
        int c=s[i]-'0';
        if(!go[now][c]) go[now][c]=++num;
        now=go[now][c];
    }
    end[now]=true;
}

queue<int> q;

void get_fail(){
    if(go[0][0]) q.push(go[0][0]);
    if(go[0][1]) q.push(go[0][1]);
    while(!q.empty()){
        int now=q.front();
        q.pop();
        for(int i=0;i<=1;i++)
         if(!go[now][i]) go[now][i]=go[fail[now]][i];
         else {
             fail[go[now][i]]=go[fail[now]][i];
             end[go[now][i]]|=end[fail[go[now][i]]];
             q.push(go[now][i]);
         }
    }
}

bool dfs(int now){
    if(end[now]) return false;
    for(int i=0;i<=1;i++)
     if(!vis[go[now][i]]){
         vis[go[now][i]]=true;
         if(dfs(go[now][i])) return true;
         vis[go[now][i]]=false;
     }
     else if(!end[go[now][i]]) return true;
    return false;
}

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%s",s),extend(strlen(s));
    get_fail();
    vis[0]=true;
    printf("%s",dfs(0) ? "TAK" : "NIE");
}
View Code

猜你喜欢

转载自www.cnblogs.com/sto324/p/11209785.html