zoukankan      html  css  js  c++  java
  • 【AC自动机】最短母串

    【题目链接】

    https://loj.ac/problem/10061

    【题意】

    给定 n 个字符串 S1~Sn,要求找到一个最短的字符串 T,使得这 n 个字符串都是 T 的子串。

    【题解】

    类似于搜索+二进制记录状态的题目

    搜索时利用BFS来跑,每一个结点的位置都可以用状态数组存起来,

    判断是否为 (1<<n)- 1 即可。

    在输出答案时需要递归实现,所以要一个辅助数组fa来记录上一个结点的位置。

      1 #include<queue>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 const int N = 6e3+5;
      7 const int M = 2e6+50;
      8 const int Str_N = 605;
      9 int Trie[N][26],fail[N],End[N];
     10 int vis[N][Str_N];
     11 int Q[M],St[M];
     12 int Fa[M];
     13 char str[M];
     14 int Head,Tail;
     15 int n,idx;
     16 char Str[Str_N];
     17 void print(int x){
     18     if(x==1) return ;
     19     print(Fa[x]);
     20     putchar(str[x]+'A');
     21 }
     22 void Insert( char s[] , int Id ){
     23     int p = 0 ;
     24     for(int i=0;s[i];i++){
     25         int t = s[i]-'A';
     26         if( !Trie[p][t] )
     27             Trie[p][t] = ++idx;
     28         p = Trie[p][t];
     29     }
     30     End[p] |= (1<<Id);
     31 }
     32 void Build(){
     33     Head = 1 , Tail = 0;
     34 
     35     for(int i=0;i<26;i++){
     36         if( Trie[0][i] ){
     37             Q[++Tail] = Trie[0][i];
     38             fail[Trie[0][i]] = 0;
     39         }
     40     }
     41 
     42     while( Head <= Tail ){
     43         int u = Q[Head++];
     44 
     45         for(int i=0;i<26;i++){
     46             int To = Trie[u][i];
     47             if( To ){
     48                 fail[To] = Trie[fail[u]][i];
     49                 Q[++Tail] = To ;
     50                 End[To] |= End[fail[To]];
     51             }else{
     52                 Trie[u][i] = Trie[fail[u]][i];
     53             }
     54         }
     55     }
     56 }
     57 void Solve(){
     58     memset(Q,0,sizeof Q );
     59 
     60 
     61     Head = 0 , Tail = 1;
     62     Q[1] = St[1] = 0 ;
     63     vis[0][0] = 1 ;
     64 
     65     while( Head < Tail ){
     66         int u = Q[++Head],S = St[Head];
     67         for(int i=0;i<26;i++){
     68             int To = Trie[u][i];
     69             int Ts = S | End[To] ;
     70             if( vis[Ts][To] ) continue;
     71 
     72             Fa[++Tail] = Head ; Q[Tail] = To ;str[Tail] = i;
     73             vis[Ts][To] = 1 ;St[Tail] = Ts ;
     74 
     75             if( Ts == (1<<n)-1 ){
     76                 print(Tail);
     77                 putchar('
    ');
     78                 return ;
     79             }
     80         }
     81     }
     82 }
     83 int main()
     84 {
     85     scanf("%d",&n);
     86     for(int i=0;i<n;i++){
     87         scanf("%s",Str);
     88         Insert(Str,i);
     89     }
     90     Build();
     91     Solve();
     92     return 0;
     93 }
     94 
     95 /*
     96  *
     97 4
     98 HNOI
     99 NOIP
    100 NOI
    101 IOI
    102 
    103 HNOIPIOI
    104  */
    View Code
  • 相关阅读:
    W3C标准
    Oracle数据库中的几个名字及监听的配置问题
    Linux中特别要注意用户与文件权限的问题
    Linux中mv重命名作用及打包war压缩文件及分配权限
    虚拟机的ip网络设置的选择
    sqlplus中登陆账户用@加上数据库sid
    bat文件从@含义起
    我原来还在这
    Hibernate的数据操作(4.*以上版本)
    Hibernate中的配置文件
  • 原文地址:https://www.cnblogs.com/Osea/p/11367043.html
Copyright © 2011-2022 走看看