洛谷2444 [POI2000]病毒(AC自动机)(DFS)

版权声明:本文为博主原创文章,未经博主允许不得转载,除非先点了赞。 https://blog.csdn.net/A_Bright_CH/article/details/83145280

题目

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

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

任务:
请写一个程序:
1.在文本文件WIR.IN中读入病毒代码;
2.判断是否存在一个无限长的安全代码;
3.将结果输出到文件WIR.OUT中。

题解

AC自动机+DFS判环
给病毒代码建字典树,并建立fail指针。
要求一个无限长的安全代码实际上就是要在AC自动机上找到一个不包含结尾标记的环,当然,如果一个fail指针指向的节点有结尾标记,那么这个点也不能选,因为到了这个节点相当于到了那个节点,也就是说它的后缀是病毒代码。
为了方便操作,我们可以把没有孩子的尾节点直接接上fail。
接下来就是一个dfs判断是否有环,注意不能走有标记的节点。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=2010,maxl=30010;
int n;
char s[maxl];

struct tree{int fail,son[2];bool c;}tr[maxl];int tot=1,root=1;

void insert()
{
    int x=root;
    int len=strlen(s+1);
    for(int i=1;i<=len;i++)
    {
        int k=s[i]-'0';
        if(!tr[x].son[k]) tr[x].son[k]=++tot;
        x=tr[x].son[k];
    }
    tr[x].c=true;
}

int head,tail,q[maxl];
void makefail()
{
    head=0,tail=1;q[0]=root;
    while(head<tail)
    {
        int x=q[head++];
        for(int k=0;k<=1;k++)
        {
            int y=tr[x].son[k];
            if(!y)
            {
                tr[x].son[k]=tr[tr[x].fail].son[k];
                continue;
            }
            int p=tr[x].fail;
            while(!tr[p].son[k]) p=tr[p].fail;
            tr[y].fail=tr[p].son[k];
            tr[y].c|=tr[tr[y].fail].c;
            q[tail++]=y;
        }
    }
}

bool vis[maxl];
void dfs(int x)
{
    vis[x]=true;
    for(int k=0;k<=1;k++)
    {
        int y=tr[x].son[k];
        if(vis[y]==true)
        {
            puts("TAK");
            exit(0);
        }
        if(y && !tr[y].c) dfs(y);
    }
    vis[x]=false;
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",s+1);
        insert();
    }
    for(int i=0;i<=1;i++) tr[0].son[i]=1;
    makefail();
    dfs(root);
    puts("NIE");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/A_Bright_CH/article/details/83145280