• BZOJ1195: [HNOI2006]最短母串(Trie图,搜索)


    Description

    给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串。

    Input

    第一行是一个正整数n(n<=12),表示给定的字符串的个数。
    以下的n行,每行有一个全由大写字母组成的字符串。每个字符串的长度不超过50.

    Output

    只有一行,为找到的最短的字符串T。在保证最短的前提下,
    如果有多个字符串都满足要求,那么必须输出按字典序排列的第一个。

    Sample Input

    2
    ABCD
    BCDABC

    Sample Output

    ABCDABC

    解题思路:

    最优解还是要Bfs的,状态这么少。

    防止其空间爆炸,采用路径记录法。

    状态为两部分:自动机上节点编号及终止子串个数。

    想开二维数组存状态,但是已知后面状态的上限,取模和除操作即为压缩。

    代码:

      1 #include<queue>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 struct trnt{
      6     int ch[26];
      7     int fl;
      8     int fin;
      9 }tr[700];
     10 int siz;
     11 int n,m;
     12 int lim;
     13 int oo;
     14 int ans[2000000];
     15 int lst[2000000];
     16 int val[2000000];
     17 char tmp[100];
     18 std::queue<int>Q,S;
     19 int zip(int plc,int sit){return plc*oo+sit;}
     20 int Plc(int bag){return bag/oo;}
     21 int Sit(int bag){return bag%oo;}
     22 void Insert(char *a,int t)
     23 {
     24     int root=0;
     25     int len=strlen(a+1);
     26     for(int i=1;i<=len;i++)
     27     {
     28         int c=a[i]-'A';
     29         if(!tr[root].ch[c])
     30             tr[root].ch[c]=++siz;
     31         root=tr[root].ch[c];
     32     }
     33     tr[root].fin|=(1<<(t-1));
     34     return ;
     35 }
     36 void Build(void)
     37 {
     38     int root=0;
     39     for(int i=0;i<26;i++)
     40         if(tr[root].ch[i])
     41             Q.push(tr[root].ch[i]);
     42     while(!Q.empty())
     43     {
     44         root=Q.front();
     45         Q.pop();
     46         tr[root].fin|=tr[tr[root].fl].fin;
     47         for(int i=0;i<26;i++)
     48         {
     49             if(tr[root].ch[i])
     50             {
     51                 tr[tr[root].ch[i]].fl=tr[tr[root].fl].ch[i];
     52                 Q.push(tr[root].ch[i]);
     53             }else
     54                 tr[root].ch[i]=tr[tr[root].fl].ch[i];
     55         }
     56     }
     57     return ;
     58 }
     59 void Bfs(void)
     60 {
     61     memset(lst,-1,sizeof(lst));
     62     lst[0]=-2;
     63     S.push(0);
     64     while(!S.empty())
     65     {
     66         int B=S.front();
     67         S.pop();
     68         int root=Plc(B);
     69         int situ=Sit(B);
     70         if(situ==oo-1)
     71         {
     72             
     73             while(lst[B]!=-2)
     74             {
     75                 
     76                 ans[++lim]=val[B];
     77                 B=lst[B];
     78             }
     79             for(int i=lim;i;i--)
     80                 putchar(ans[i]+'A');
     81             puts("");
     82             return ;
     83         }
     84         for(int i=0;i<26;i++)
     85         {
     86             
     87             int nwrt=tr[root].ch[i];
     88             int nwst=situ|tr[nwrt].fin;
     89             int nwB=zip(nwrt,nwst);
     90             if(~lst[nwB])
     91                 continue;
     92             lst[nwB]=B;
     93             val[nwB]=i;
     94             S.push(nwB);
     95         }
     96     }
     97     return ;
     98 }
     99 int main()
    100 {
    101     //freopen("tmp.in","r",stdin);
    102     scanf("%d",&n);    oo=1<<n;
    103     for(int i=1;i<=n;i++)
    104     {
    105         scanf("%s",tmp+1);
    106         Insert(tmp,i);
    107     }
    108     Build();
    109     Bfs();
    110     return 0;
    111 }
  • 相关阅读:
    无责任Windows Azure SDK .NET开发入门篇二[使用Azure AD 进行身份验证]
    无责任Windows Azure SDK .NET开发入门篇一[Windows Azure开发前准备工作]
    了解ASP.NET5 Web应用程序结构
    Hello ASP.NET5
    CentOS7 防火墙 firewall-cmd
    C# 中使用WebClient 请求 https
    使用 gridfs-stream 存储文件遇到的一个坑。
    overflow的几个坑
    IIS7启用静态压缩
    创建高性能移动 web 站点【转载】
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10014032.html
Copyright © 2020-2023  润新知