bzoj2938 [Poi2000]病毒
如果可以按照一个循环节一直循环而不会被匹配到,那么就安全了
所以在AC自动机上找环就可以了
为什么会T呢?找环挂了,开两个bool数组快很多啊。。。涨姿势了
T掉代码:
bool bo[30030]; bool dfs(int x) { bo[x]=1; re(i,0,1) { if(bo[ch[x][i]])return 1; if(v[ch[x][i]])continue; if(dfs(ch[x][i]))return 1; } bo[x]=0; return 0; }
AC:
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<string> 7 #include<cmath> 8 #include<ctime> 9 #include<queue> 10 #include<stack> 11 #include<map> 12 #include<set> 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--) 14 #define re(i,l,r) for(int i=(l);i<=(r);i++) 15 #define Clear(a,b) memset(a,b,sizeof(a)) 16 #define inout(x) printf("%d",(x)) 17 #define douin(x) scanf("%lf",&x) 18 #define strin(x) scanf("%s",(x)) 19 #define LLin(x) scanf("%lld",&x) 20 #define op operator 21 #define CSC main 22 typedef unsigned long long ULL; 23 typedef const int cint; 24 typedef long long LL; 25 using namespace std; 26 void inin(int &ret) 27 { 28 ret=0;int f=0;char ch=getchar(); 29 while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();} 30 while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar(); 31 ret=f?-ret:ret; 32 } 33 int n,ch[30030][2],pre[30030],ed=1,v[30030]; 34 char s[30030]; 35 void add(char *s) 36 { 37 int len=strlen(s),x=1; 38 re(i,0,len-1) 39 { 40 int c=s[i]-'0'; 41 if(!ch[x][c])ch[x][c]=++ed; 42 x=ch[x][c]; 43 } 44 v[x]=1; 45 } 46 queue<int>h; 47 void getfail() 48 { 49 h.push(1);pre[0]=1; 50 while(!h.empty()) 51 { 52 int x=h.front();h.pop(); 53 re(i,0,1) 54 { 55 if(!ch[x][i]) 56 { 57 ch[x][i]=ch[pre[x]][i]; 58 continue; 59 } 60 int y=ch[x][i]; 61 int k=pre[x]; 62 while(!ch[k][i])k=pre[k]; 63 pre[y]=ch[k][i]; 64 v[y]=max(v[y],v[ch[k][i]]); 65 h.push(y); 66 } 67 } 68 } 69 bool bo[30030],bb[30030]; 70 bool dfs(int x) 71 { 72 bo[x]=1; 73 re(i,0,1) 74 { 75 if(bo[ch[x][i]])return 1; 76 if(bb[ch[x][i]]||v[ch[x][i]])continue; 77 bb[ch[x][i]]=1; 78 if(dfs(ch[x][i]))return 1; 79 } 80 bo[x]=0; 81 return 0; 82 } 83 int main() 84 { 85 ch[0][1]=ch[0][0]=1; 86 inin(n); 87 re(i,1,n) 88 { 89 strin(s); 90 add(s); 91 } 92 getfail(); 93 if(!dfs(1))printf("NIE\n"); 94 else cout<<"TAK\n"; 95 return 0; 96 }