bzoj2938: [Poi2000]病毒

来源:互联网 发布:lr监控windows资源 编辑:程序博客网 时间:2024/06/05 11:52

传送门:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2938

思路:构建AC自动机,无限长的安全代码就是能一直在AC自动机上匹配而匹配不上任何一个危险串。依旧是匹配指针不能走到危险串的结尾点x,fail指针指向x的y也不能走,因为根据fail的定义,x这个危险串是y的后缀。找出危险节点后就是找环了,有环就有无限长的安全代码,否则没有。

#include<cstdio>#include<cstring>#include<algorithm>const int maxn=30010;using namespace std;int n;char s[maxn];struct AC_DFA{int tot,ch[maxn][2],fail[maxn],q[maxn],head,tail;bool dang[maxn],bo[maxn],ins[maxn];void insert(){int p=0;for (int i=0;i<(int)strlen(s);p=ch[p][s[i]-'0'],i++) if (!ch[p][s[i]-'0']) ch[p][s[i]-'0']=++tot;dang[p]=1;}void getfail(){head=0,q[tail=1]=0,fail[0]=-1;while (head!=tail){int x=q[++head];for (int i=0;i<=1;i++)if (ch[x][i])q[++tail]=ch[x][i],fail[ch[x][i]]=x==0?0:ch[fail[x]][i],dang[ch[x][i]]|=dang[fail[ch[x][i]]];else ch[x][i]=x==0?0:ch[fail[x]][i];}}bool dfs(int x){ins[x]=1;for (int i=0;i<=1;i++){int v=ch[x][i];if (ins[v]) return 1;if (bo[v]||dang[v]) continue;bo[v]=1;if (dfs(v)) return 1;}ins[x]=0;return 0;}}T;int main(){scanf("%d",&n);for (int i=1;i<=n;i++) scanf("%s",s),T.insert();T.getfail(),puts(T.dfs(0)?"TAK":"NIE");return 0;}


0 0
原创粉丝点击