• HNOI2006 最短母串问题


    题目描述:

    题解:

    先见出Trie图,然后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;
    }
  • 相关阅读:
    ansible-playbook最佳实践
    zabbix 优化之 表分区
    ansible-playbook 打通ssh无秘钥
    jQuery 1.9 移除了 $.browser 的替代方法
    也谈前端基础设施建设
    滚动视差网站欣赏
    css常见的快捷开发代码汇总(长期更新)
    如何让搜索引擎抓取AJAX内容?
    Bookmarklet编写指南
    20个网页设计师应该学习的CSS3经典教程实例
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10046217.html
Copyright © 2020-2023  润新知