bzoj 1195: [HNOI2006]最短母串

MEL卡空间干嘛。。。

不过代码应该没有问题

/*
    建立AC自动机 
    然后按照字典序跑bfs
    直到找到组合要求的字符串 
*/
#include<queue> 
#include<cstdio>
#include<cstring>
#define mp make_pair
using namespace std;
const int N=2500050;
int n,tot,fa[N],a[N];
bool b[1005][1<<12];
struct tree 
{
    int son[26],id,now,nxt;
    tree()
    {
        for(int i=0;i<26;i++) son[i]=0;
        id=now=nxt=0;
    }
} f[N];
void insert(char*s,int k)
{
    int len=strlen(s+1),u=0;
    for(int i=1;i<=len;i++)
    {
        int v=s[i]-'A'; 
        if(!f[u].son[v]) 
            f[u].son[v]=++tot,f[u].id=tot;
        u=f[u].son[v];
    }
    f[u].now=(1<<k)>>1;
}
void ac()
{
    queue< int > q;
    for(int i=0;i<26;i++) if(f[0].son[i])
        q.push(f[0].son[i]);
    while(!q.empty())
    {
        int u=q.front();q.pop();
        for(int i=0;i<26;i++) 
            if(f[u].son[i]) 
                f[f[u].son[i]].nxt=f[f[u].nxt].son[i],
                q.push(f[u].son[i]);
            else f[u].son[i]=f[f[u].nxt].son[i];
        int v=f[u].nxt;
        while(v&&f[v].now==0) v=f[v].nxt;
        f[u].now|=f[v].now;// 找一个最近的后缀就可以包含所有后缀 
    }
}
void print(int x)
{
    if(!x) return ;
    print(fa[x]);
    putchar('A'+a[x]);
}
void solve()
{
    queue< pair< int,pair< int,int > > > q;
    q.push(mp(0,mp(f[0].now,0)));
    b[0][f[0].now]=1;
    while(!q.empty())
    {
        pair< int,pair< int,int > > x=q.front();q.pop();
        int id=x.second.second;
        int now=x.second.first;
        int u=x.first;
        if(now==(1<<n)-1) {print(id);return ;} 
        for(int i=0;i<26;i++)
        {
            int k=now|f[f[u].son[i]].now;
            if(b[f[f[u].son[i]].id][k]) continue;
            b[f[f[u].son[i]].id][k]=1;
            fa[++tot]=id;a[tot]=i;
            q.push(mp(f[u].son[i],mp(k,tot)));
        }
    }
}
int main()
{
    scanf("%d",&n) ; char s[100];
    for(int i=1;i<=n;i++) scanf("%s",s+1),insert(s,i);
    ac(); 
    solve();
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/lxy8584099/p/10359367.html
今日推荐