zoukankan      html  css  js  c++  java
  • bzoj2938: [Poi2000]病毒

    题解:对于一组病毒编码,我们构建AC自动机。如果存在一个无限长的安全代码,它在里面匹配,将一直匹配不上,也就是说,失配边会形成一个环。

    所以构建好AC自动机后dfs失配边看有无环即可。

    上代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 30005
     4 int n; char ch[N];
     5 struct acc
     6 {
     7     int f[N],next[N][2],cnt,head,tail,q[N];
     8     bool vis[N],ins[N],danger[N];
     9     acc(){
    10         cnt=0;
    11         memset(vis,0,sizeof(vis));
    12         memset(ins,0,sizeof(ins));
    13         memset(danger,0,sizeof(danger));
    14     }
    15     void inser(){
    16         scanf("%s",ch); int p=0,len=strlen(ch);
    17         for(int a,i=0;i<len;i++){
    18             a=ch[i]-'0';
    19             if(!next[p][a]) next[p][a]=++cnt;
    20             p=next[p][a];
    21         } danger[p]=1;
    22     }
    23     void getfail(){
    24         head=0; tail=0;
    25         for(int i=0;i<2;i++) if(next[0][i]) q[tail++]=next[0][i],f[next[0][i]]=0;
    26         //一定不要直接把0丢进队列BFS,要分别把每个单独拿出来,不然是错的 
    27         while(head<tail){
    28             int p=q[head++];
    29             for(int i=0;i<2;i++){
    30                 int v=next[p][i];
    31                 if(!v) {next[p][i]=next[f[p]][i]; continue;}
    32                 int k=f[p];
    33                 while(k && !next[k][i]) k=f[k]; k=next[k][i];
    34                 f[v]=k;
    35                  danger[v]|=danger[k];
    36                 q[tail++]=v;
    37             }
    38         }
    39     }
    40     bool dfs(int x){
    41         ins[x]=1;
    42         for(int i=0;i<2;i++){
    43             int v=next[x][i];
    44             if(ins[v]) return 1;
    45             if(vis[v] || danger[v]) continue;
    46             vis[v]=1;
    47             if(dfs(v)) return 1;
    48         }
    49         ins[x]=0;
    50         return 0;
    51     }
    52 }acm;
    53 int main(){
    54     scanf("%d",&n);
    55     for(int i=1;i<=n;i++) acm.inser();
    56     acm.getfail();
    57     if(acm.dfs(0)) puts("TAK");
    58     else puts("NIE");
    59     return 0;
    60 }
  • 相关阅读:
    多表查询练习
    mysql查询练习
    mysql建表练习
    超详细mysql left join,right join,inner join用法分析
    Elasticsearch搜索引擎版本配置
    centos 开启apache rewrite模式
    centos 下 apache 重启启动命令
    centos 下使用sublime
    ThinkPHP Where 条件中使用表达式
    转载自php100中文网 centos下lamp 环境搭建
  • 原文地址:https://www.cnblogs.com/enigma-aw/p/6179308.html
Copyright © 2011-2022 走看看