bzoj2938: [Poi2000]病毒
建AC自动机,把所有病毒的节点都删掉,dfs判有没有环,有环就找得到。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> #define N 30304 using namespace std; int size,root; int next[N][2],fail[N]; bool safe[N]; int newnode(){ safe[++size]=1; next[size][0]=next[size][1]=0; return size; } void ins(char *s){ int now=root; for (int i=0;s[i];++i){ if (!next[now][s[i]-48]) next[now][s[i]-48]=newnode(); now=next[now][s[i]-48]; } safe[now]=0; } int q[N],qh,qt; void bfs(){ fail[root]=root; qh=qt=0; q[++qt]=root; while (qh<qt){ int u=q[++qh]; for (int i=0;i<2;++i){ int v=next[u][i]; if (!v) next[u][i]=u!=root?next[fail[u]][i]:root; else{ fail[v]=u!=root?next[fail[u]][i]:root; q[++qt]=v; } } safe[u]&=safe[fail[u]]; } } bool vis[N],found; bool flag[N]; void dfs(int u){ vis[u]=1; for (int i=0;i<2;++i){ int v=next[u][i]; if (!safe[v]) continue; if (vis[v]) found=1; else dfs(v); if (found) return; } vis[u]=0; safe[u]=0; } char s[N]; int main(){ int n;scanf("%d",&n); size=0;root=newnode(); memset(s,0,sizeof(s)); for (int i=1;i<=n;++i){ scanf("%s",s); ins(s); } bfs(); memset(vis,0,sizeof(vis)); found=0; dfs(root); puts(found?"TAK":"NIE"); return 0; }