[bzoj2938][Poi2000]病毒

本文介绍了一种使用自动机进行字符串匹配的方法,并通过构建后缀自动机来判断是否存在一条从根节点出发不经过任何标记节点的路径,进而判断是否能够形成闭环。此算法应用于多次初始化后的自动机,最终确定是否存在这样的闭环。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Orz w_yqts trie图dalao
建完自动机判断是否能跑出环(不能经过有价值的点或后缀)

#include <bits/stdc++.h>
using namespace std;
#define N 66666
char s[N];
int trie[N][2],point[N],tottrie;
int danger[N],instk[N];
int q[N],vis[N];
void init()
{
    scanf("%s",s);
    int len=strlen(s);
    int now=0;
    for (int i=0;i<len;++i)
    {
        int t=s[i]-'0';
        if (trie[now][t]) now=trie[now][t];else now=trie[now][t]=++tottrie;
    }
    danger[now]=1;
}
void AC()
{
    int st=0,ed=1;
    q[1]=0;
    while (st<ed)
    {
        int now=q[++st];
        for (int i=0;i<2;++i)
        {
            if (trie[now][i]) point[trie[now][i]]=(now==0)?0:trie[point[now]][i],q[++ed]=trie[now][i],danger[trie[now][i]]|=danger[trie[point[now]][i]];
            else trie[now][i]=trie[point[now]][i];
        }
    }
}
int Orzwyqts=0;
void dfs(int x)
{
    vis[x]=1;
    instk[x]=1;
    if (Orzwyqts) return;
    for (int i=0;i<2;++i)
    if (!danger[trie[x][i]])
    {
        if (instk[trie[x][i]]) {Orzwyqts=1;return;}
        if (vis[trie[x][i]]) continue;
        if (Orzwyqts) return;
        dfs(trie[x][i]);
        if (Orzwyqts) return;
    }
    if (Orzwyqts) return;
    instk[x]=0;
}
int main()
{
    int m;
    cin>>m;
    while (m--) init();
    AC();
    dfs(0);
    if (Orzwyqts) puts("TAK");else puts("NIE");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值