欢迎访问~原文出处——博客园-zhouzhendong

去博客园看该题解


传送门 - BZOJ1195


题意概括

  给出一堆串,然后求一个包含这些串的所有串的最短的中的字典序最小的。


题解

  先造一个AC自动机,多模匹配嘛。

  然后bfs在AC自动机上面走,两维状态,dis[i][j]表示已经走到过的串状态为i,在AC自动机上面的位置为j的最短距离。

  然后这题居然要卡空间!

  坑死了。

  然后用了short

  wa掉了。

  发现short实在小的可怜,然后把几个大的数组的有必要的一个开了int,然后30MB卡着限制过去了~

  开心!!


代码

  1. #include <cstring>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <cstdlib>
  5. #include <cmath>
  6. using namespace std;
  7. struct Trie{
  8. int e,fail,next[];
  9. void init(){
  10. e=fail=;
  11. memset(next,,sizeof next);
  12. }
  13. }tree[];
  14. int cnt;
  15. void AC_Prepare(){
  16. cnt=;
  17. tree[].init(),tree[].init();
  18. for (int i=;i<;i++)
  19. tree[].next[i]=;
  20. }
  21. void add(char ch[],int bh){
  22. int len=strlen(ch),rt=,t;
  23. for (int i=;i<len;i++){
  24. t=ch[i]-'A';
  25. if (!tree[rt].next[t]){
  26. tree[++cnt].init();
  27. tree[rt].next[t]=cnt;
  28. }
  29. rt=tree[rt].next[t];
  30. }
  31. tree[rt].e|=<<bh;
  32. }
  33. void build_AC(){
  34. int q[],head=,tail=,rt,son,k;
  35. tree[].fail=,q[++tail]=;
  36. while (head<tail){
  37. rt=q[++head];
  38. for (int i=;i<;i++){
  39. son=tree[rt].next[i];
  40. if (!son){
  41. tree[rt].next[i]=tree[tree[rt].fail].next[i];
  42. continue;
  43. }
  44. k=tree[rt].fail;
  45. while (!tree[k].next[i])
  46. k=tree[k].fail;
  47. tree[son].fail=tree[k].next[i];
  48. tree[son].e|=tree[tree[k].next[i]].e;
  49. q[++tail]=son;
  50. }
  51. }
  52. }
  53. int n,head,tail,pre[<<][];
  54. short dis[<<][];
  55. bool f[<<][];
  56. char str[],chosen[<<][],ansstr[];
  57. struct Queue{
  58. short x,y;
  59. void push(int a,int b){
  60. x=a,y=b;
  61. }
  62. void pushout(int &a,int &b){
  63. a=x,b=y;
  64. }
  65. }q[];
  66. int main(){
  67. scanf("%d",&n);
  68. AC_Prepare();
  69. for (int i=;i<n;i++){
  70. scanf("%s",str);
  71. add(str,i);
  72. }
  73. build_AC();
  74. memset(f,,sizeof f);
  75. memset(dis,,sizeof dis);
  76. memset(q,,sizeof q);
  77. head=tail=;
  78. q[++tail].push(,);
  79. dis[][]=,f[][]=,pre[][]=;
  80. int ans=-,x,y,x_,y_;
  81. while (head<tail){
  82. q[++head].pushout(x,y);
  83. for (int i=;i<;i++){
  84. y_=tree[y].next[i];
  85. x_=x|tree[y_].e;
  86. if (f[x_][y_])
  87. continue;
  88. dis[x_][y_]=dis[x][y]+;
  89. chosen[x_][y_]=i;
  90. pre[x_][y_]=head;
  91. f[x_][y_]=;
  92. q[++tail].push(x_,y_);
  93. if (x_==(<<n)-){
  94. ans=tail;
  95. break;
  96. }
  97. }
  98. if (ans!=-)
  99. break;
  100. }
  101. q[ans].pushout(x,y);
  102. int ansdis=dis[x][y],xnow,ynow;
  103. for (int j=ansdis,i=ans;j>=&&i;j--,i=pre[xnow][ynow]){
  104. q[i].pushout(xnow,ynow);
  105. ansstr[j]=chosen[xnow][ynow]+'A';
  106. }
  107. for (int i=;i<=ansdis;i++)
  108. printf("%c",ansstr[i]);
  109. return ;
  110. }

BZOJ1195 [HNOI2006]最短母串 AC自动机 bfs的更多相关文章

  1. BZOJ1195[HNOI2006]最短母串——AC自动机+BFS+状态压缩

    题目描述 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. 输入 第一行是一个正整数n(n<=12),表示给定的字符串的 ...

  2. Bzoj1195 [HNOI2006]最短母串 [AC自动机]

    Time Limit: 10 Sec  Memory Limit: 32 MBSubmit: 1304  Solved: 439 Description 给定n个字符串(S1,S2,„,Sn),要求找 ...

  3. bzoj1195 [HNOI2006]最短母串 AC 自动机+状压+bfs

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1195 题解 建立 AC 自动机,然后构建出 trie 图. 然后直接在 trie 图上走.但是 ...

  4. BZOJ_1195_[HNOI2006]最短母串_AC自动机+BFS+分层图

    BZOJ_1195_[HNOI2006]最短母串_AC自动机+BFS+分层图 Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2, ...

  5. 【bzoj1195】[HNOI2006]最短母串 AC自动机+状态压缩+BFS最短路

    原文地址:http://www.cnblogs.com/GXZlegend/p/6825226.html 题目描述 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串 ...

  6. [HNOI2006]最短母串 (AC自动机+状压)

    Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. Input 第一行是一个正整数n(n<=12) ...

  7. BZOJ 1195: [HNOI2006]最短母串 AC自动机+状压+搜索

    思路比较直接. 由于 $n$ 很小,直接定义 $f[i][j]$ 表示当前在自动机中的节点 $i,$ 被覆盖串的集合为 $j$ 的方案数. #include <bits/stdc++.h> ...

  8. [bzoj1195][HNOI2006]最短母串_动态规划_状压dp

    最短母串 bzoj-1195 HNOI-2006 题目大意:给一个包含n个字符串的字符集,求一个字典序最小的字符串使得字符集中所有的串都是该串的子串. 注释:$1\le n\le 12$,$1\le ...

  9. Bzoj1195 [HNOI2006]最短母串 [状态压缩]

    Time Limit: 10 Sec  Memory Limit: 32 MBSubmit: 1304  Solved: 439 Description 给定n个字符串(S1,S2,„,Sn),要求找 ...

随机推荐

  1. C# CEF 封装UserControl

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; u ...

  2. Python中的包ImportError

    前言 Python中的包给我提供了很好的代码组织,相似的功能模块放在同一个包内,不仅代码结构清晰,而且调用起来也比较方便(可以用*导入) 但是,我们在刚开始使用Python包的时候总是会遇到导入错误& ...

  3. Javaweb学习笔记——(四)——————JavaScript基础&DOM目录

    1.案例一:在末尾添加节点 第一个:获取到ul标签 第二部:创建li标签 document.createElement("标签名称")方法 第三步:创建文本 document.cr ...

  4. 二、主目录 Makefile 分析(1)

    2.1 uboot 版本号 uboot 的版本号分三个级别: VERSION:主版本号 PATCHLEVEL:次版本号,为补丁级别 SUBLEVEL:再次版本号 EXTRAVERSION:附加版本信息 ...

  5. socket 聊天室

    服务端: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; ...

  6. wpc 双工

    在控制台部署wcf双工 这个可以被silverlight 使用 <?xml version="1.0" encoding="utf-8" ?> &l ...

  7. Linux之Ubuntu安装搜狗输入法

    1.下载搜狗输入法安装包 搜狗官网:https://pinyin.sogou.com/linux/ 2.更新ubuntu内置的包管理器apt-get的软件源[如果中途安装失败,经常是此原因造成的] s ...

  8. django(一)验证码

    这里讲讲在django中使用第三方插件验证码的流程. 一. 先安装pillow, 通过 python -m pip install pillow 二.安装完后,在官方网站上看操作过程.地址:pillo ...

  9. mysql架构解读~mysql的多源复制

    一 场景需求 多源复制版本 5.7,目标主机5.6.21 4个DB机器的某些数据库需要数据汇总进行连表查询 二 进行搭建  1 导出相应的目的库     mysqldump -uuser -ppass ...

  10. Fragment的常用写法

    一般通过add.show.hide相结合的方法来控制Fragment的显示和隐藏,这样不会再重写一遍Fragment的生命周期,节省了时间和内存,当然特殊需求除外. package com.examp ...