• BZOJ 1195: [HNOI2006]最短母串 AC自动机+状压+搜索


    思路比较直接. 

    由于 $n$ 很小,直接定义 $f[i][j]$ 表示当前在自动机中的节点 $i,$ 被覆盖串的集合为 $j$ 的方案数.   

    #include <bits/stdc++.h>  
    #define N 750
    #define M 150000 
    #define setIO(s) freopen(s".in","r",stdin) , freopen(s".out","w",stdout)    
    using namespace std;  
    int n,tot,edges,kk;     
    int Log[30],hd[N],to[N],nex[N],mark[N][5000],fa[M*10],C[M*10];      
    char str[N];   
    queue<int>q;  
    struct Sta 
    { 
        int u,sta,id;  
        Sta(int u=0,int sta=0,int id=0):u(u),sta(sta),id(id){}      
    };         
    queue<Sta>Q;   
    struct Node  
    {
        int sta,f,tag,ch[27];  
    }t[N];            
    void add(int u,int v) 
    {
        nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;   
    }      
    void insert(int xx) 
    { 
        int p=0,i,j,len=strlen(str+1);    
        for(i=1;i<=len;++i) 
        {
            int c=str[i]-'A'; 
            if(!t[p].ch[c]) t[p].ch[c]=++tot;    
            p=t[p].ch[c];    
        } 
        t[p].tag=1;   
        t[p].sta|=Log[xx];   
    }   
    void build() 
    { 
        int i,j; 
        for(i=0;i<27;++i) if(t[0].ch[i]) q.push(t[0].ch[i]),add(0,t[0].ch[i]);   
        for(;!q.empty();) 
        {
            int u=q.front();q.pop();   
            for(i=0;i<27;++i) 
            {
                int qq=t[u].ch[i];    
                if(!qq) 
                {
                    t[u].ch[i]=t[t[u].f].ch[i];  
                    continue;   
                } 
                t[qq].f=t[t[u].f].ch[i];         
                add(t[qq].f,qq);   
                q.push(qq);  
            }
        }
    } 
    // 继承自己.    
    void dfs(int x) 
    {
        for(int i=hd[x];i;i=nex[i]) 
        {
            int v=to[i];  
            t[v].sta|=t[x].sta; 
            dfs(v);          
        }  
    }   
    void print(int c) 
    { 
        if(C[c]==-1) return;    
        print(fa[c]);   
        printf("%c",C[c]+'A');    
    }
    int main() 
    { 
        int i,j; 
        scanf("%d",&n);  
        for(i=1;i<=14;++i) Log[i]=(1<<(i-1));   
        for(i=1;i<=n;++i) scanf("%s",str+1),insert(i);   
        build(),dfs(0),C[0]=-1;                     
        for(Q.push(Sta(0,0,kk)),mark[0][0]=1;!Q.empty();) 
        {
            Sta e=Q.front(); Q.pop();       
            if(e.sta==Log[n+1]-1)     
            {   
                print(e.id);   
                return 0;    
            }    
            int v;    
            int u=e.u; 
            int idx=e.id;    
            int sta=e.sta;   
            for(i=0;i<27;++i) 
            {    
                v=t[u].ch[i];  
                if(!v) continue;        
                if(mark[v][sta|t[v].sta]) 
                {
                    continue;  
                }
                ++kk; 
                fa[kk]=idx;              
                C[kk]=i;    
                mark[v][sta|t[v].sta]=1;          
                Q.push(Sta(v,(sta|t[v].sta),kk));               
            }
        }
        return 0;        
    }
    

      

  • 相关阅读:
    JS实现菜单滚动到一定高度后固定
    原生js如何获取某一元素的高度
    在Vue项目中,添加的背景图片在服务器上不显示,如何处理
    单行文本截断 text-overflow
    使用line-height垂直居中在安卓手机上效果不好
    css 苹方字体
    十二. for of 示例 (可以解决大多数应用场景)
    npm详解
    webpack搭建服务器,随时修改刷新
    探讨弹性布局Flexible Box
  • 原文地址:https://www.cnblogs.com/guangheli/p/11551821.html
Copyright © 2020-2023  润新知