zoukankan      html  css  js  c++  java
  • [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("
    ");
                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;
    }
  • 相关阅读:
    添加活动记录的小坑
    用windows的批处理文件批量更改文件后缀
    js日期的初始化的格式
    对象的继承
    关于换行字符的问题
    js获取dom对象style样式的值
    判断邮箱是否合法
    Python控制函数运行时间
    如何用python编写一个计时器的程序
    TF-IDF算法介绍及实现
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10012538.html
Copyright © 2011-2022 走看看