[HNOI2006]最短母串问题

题目大意:

求包含n个串的长度最短,且字典序最小的串。

题解:

AC自动机/Trie图 + bfs。

我用的是Trie图。

把所有串扔到Trie树上,Trie图建fail指针。

然后的bfs搜索路径。

遍历时从小到大,可以保证字典序最小。

状态中压入各个子串出现过/为出现过。

代码:

#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 15
int n,tot;
char ch[N][55];
struct Trie
{
    int ch[28],fl,w;
}tr[650];
void trie_pic()
{
    queue<int>q;
    for(int i=1;i<=26;i++)
        if(tr[0].ch[i])
            q.push(tr[0].ch[i]);
    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        for(int i=1;i<=26;i++)
        {
            int &v = tr[u].ch[i];
            if(!v)
            {
                v=tr[tr[u].fl].ch[i];
                continue;
            }
            tr[v].fl = tr[tr[u].fl].ch[i];
            tr[v].w|=tr[tr[v].fl].w;
            q.push(v);
        }
    }
}
struct node
{
    int x,y;
    node(){}
    node(int x,int y):x(x),y(y){}
}tp;
bool vis[605][4100];
int col[2480500],fa[2480500],sta[605],tl;
void bfs()
{
    queue<node>q;
    q.push(node(0,0));
    int f=0,sum=0;
    while(!q.empty())
    {
        tp = q.front();q.pop();
        int x = tp.x,y = tp.y;
        if(y==(1<<n)-1)
        {
            for(int i=f;i;i=fa[i])
                sta[++tl]=col[i];
            for(int i=tl;i>=1;i--)
                printf("%c",sta[i]+'A'-1);
            printf("\n");
            return ;
        }
        for(int i=1;i<=26;i++)
        {
            int v = tr[x].ch[i];
            if(!vis[v][y|tr[v].w])
            {
                vis[v][y|tr[v].w]=1;
                sum++;
                fa[sum]=f;
                col[sum]=i;
                q.push(node(v,y|tr[v].w));
            }
        }
        f++;
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",ch[i]+1);
        int u = 0,len = strlen(ch[i]+1);
        for(int j=1;j<=len;j++)
        {
            int c = ch[i][j]-'A'+1;
            if(!tr[u].ch[c])tr[u].ch[c]=++tot;
            u=tr[u].ch[c];
        }
        tr[u].w|=(1<<(i-1));
    }
    trie_pic();
    bfs();
    return 0;
}

 

posted @ 2018-11-24 16:27  LiGuanlin  阅读(264)  评论(0编辑  收藏  举报