• bzoj1195 神奇的ac自动机+状态压缩dp


    /*

    难的不是ac自动机,是状态压缩dp 

    之前做了一两题类似题目,感觉理解的还不够透彻

    */

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int mxn=605;
    int L1[mxn*(1<<12)],L2[mxn*(1<<12)];
    queue<int>q1,q2;
    bool vis[mxn][(1<<12)];
    int n;
    int ans[mxn],num=0;
    struct ACa{
        int t[mxn][26];
        int fail[mxn];
        int end[mxn];
        int S,cnt;
        int q[670],hd,tl;
        void init(){S=cnt=1;memset(end,0,sizeof end);return;}
        void insert(char *s,int id){
            int len=strlen(s),now=S;
            for(int i=0;i<len;i++){
                if(!t[now][s[i]-'A'])t[now][s[i]-'A']=++cnt;
                now=t[now][s[i]-'A'];
            }
            end[now]|=(1<<id);
        }
        void Build(){
            hd=1;tl=0;
            for(int i=0;i<26;i++)
                if(t[S][i]){q[++tl]=t[S][i];fail[t[S][i]]=S;}
                else t[S][i]=S;
            while(hd<=tl){
                int u=q[hd++];
                int v,r;
                for(int i=0;i<26;i++){
                    if(t[u][i]){
                        fail[t[u][i]]=t[fail[u]][i];
                        end[t[u][i]]|=end[t[fail[u]][i]];
                        q[++tl]=t[u][i];
                    }
                    else t[u][i]=t[fail[u]][i];
                }
            }
            return;
        }
        void solve(){
            hd=1;tl=1;int ed=(1<<n)-1;
            q1.push(S),q2.push(0);
            while(hd<=tl){
                int u=q1.front();q1.pop();
                int e=q2.front();q2.pop();
    //            printf("  e:%d
    ",e);
                if(e==ed){//结束状态 
                    for(;hd>1;hd=L2[hd]){ans[++num]=L1[hd];}
                    for(int i=num;i;i--)printf("%c",ans[i]+'A');
                    return;
                }
                for(int i=0;i<26;i++){
                    if(!vis[t[u][i]][e|end[t[u][i]]]){
                        L1[++tl]=i;
                        L2[tl]=hd;
                        q1.push(t[u][i]);
                        q2.push(e|end[t[u][i]]);
                        vis[t[u][i]][e|end[t[u][i]]]=1;
                    }
                }
                hd++;
            }
        }
    }ac;
    char s[60];
    int main(){
        int i,j;
        scanf("%d",&n);
        ac.init();
        for(i=0;i<n;i++)scanf("%s",s),ac.insert(s,i);
    //    for(i=1;i<=ac.cnt;i++)if(ac.end[i])printf("%d %d
    ",i,ac.end[i]);
        ac.Build();
        ac.solve();
        return 0;
    }
  • 相关阅读:
    判断是否是唯一索引异常
    Sign in with Apple java
    spring 集成钉钉机器人
    list一个字段去重
    Math_Linear_algebra_05_正定矩阵
    Math_Linear_algebra_02_矩阵与线性方程
    Math_Calculus_04_多变量微积分
    Math_Linear_algebra_01_向量空间
    Linux_Best Practice_04_Ubuntu 18.04
    PMP_Previw
  • 原文地址:https://www.cnblogs.com/zsben991126/p/9797221.html
Copyright © 2020-2023  润新知