bzoj2938poi2000病毒
Posted paul-guderian
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj2938poi2000病毒相关的知识,希望对你有一定的参考价值。
-
题解:
- 对病毒串建立ac自动机;
- 有一个无限长的串等价于可以一直在自动机上匹配,等价于自动机上的转移有环;
- 当然前提是去掉病毒节点的fail子树;
- 写一个dfs记录是否在栈中,来过没有找到就不必再来了再记录一个vis保证复杂度;
- 然而。。。。。。我在找环的时候呆了很久,最后写了tarjan;
- 如果你也是有些tarjan的危险想法的话注意特判转移的自环的情况;
-
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=30010; 4 int n,sz,ch[N][2],fl[N],que[N],head,tail,vis[N],hd[N],o,dfn[N],idx,low[N],fg; 5 struct Edge{int v,nt;}E[N<<1]; 6 char s[N]; 7 void get_fl(){ 8 for(int i=0;i<2;i++)q[++tail]=ch[u][i],adde(0,ch[u][i]); 9 while(head<tail){ 10 int u=que[++head]; 11 for(int i=0;i<2;i++){ 12 int&v=ch[u][i]; 13 if(!v){v=ch[fl[u]][i];continue;} 14 fl[v]=ch[fl[u]][i]; 15 if(!vis[v])adde(v,ch[v][i]),adde(v,fl[v][i]); 16 } 17 } 18 } 19 void tarjan(int u){ 20 if(fg)return ; 21 que[++head]=u; 22 dfn[u]=low[u]=++idx; 23 for(int i=hd[u];~i;i=E[i].nt){ 24 int v=E[i].v; 25 if(!dfn[v])tarjan(v),low[u]=min(low[u],low[v]); 26 else if(!del[v])low[u]=min(low[u],dfn[v]); 27 } 28 if(dfn[u]==low[u]){ 29 int cnt=0; 30 do{ 31 int v=que[head--]; 32 cnt++; 33 }while(v!=u); 34 if(cnt > 1)fg=1; 35 } 36 } 37 int main(){ 38 freopen("bzoj2938.in","r",stdin); 39 freopen("bzoj2938.out","w",stdout); 40 scanf("%d",&n); 41 for(int i=1;i<=n;i++){ 42 scanf("%s",s+1); 43 int len=strlen(s+1),u=0; 44 for(int j=1;j<=len;j++){ 45 if(!ch[u][s[j]-‘0‘])ch[u][s[j]-‘0‘]=++sz; 46 u=ch[u][s[j]-‘0‘]; 47 } 48 vis[u]=1; 49 } 50 head=0; 51 get_fl(); 52 tarjan(0); 53 if(fg)puts("TAK");else puts("NIE";) 54 return 0; 55 }
- 对病毒串建立ac自动机;
以上是关于bzoj2938poi2000病毒的主要内容,如果未能解决你的问题,请参考以下文章