题目传送门

https://lydsy.com/JudgeOnline/problem.php?id=1195

题解

建立 AC 自动机,然后构建出 trie 图。

然后直接在 trie 图上走。但是我们需要经过每一个串。

所以我们处理一下每个点代表了哪些串,然后把状态加入进 bfs 状态。

然后 bfs 就可以了。


\(O(n)\)。

#include<bits/stdc++.h>

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;} typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii; template<typename I> inline void read(I &x) {
int f = 0, c;
while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
x = c & 15;
while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
f ? x = -x : 0;
} const int N = 12 + 1;
const int M = 50 + 1;
const int NM = 12 * 50 + 1;
const int NP = (1 << 12);
const int NMP = 12 * 50 * ((1 << 12) - 1) + 1; int n, m, nod;
int q[NMP], q2[NMP], fr[NM][NP];
char s[N], ans[NM];
struct Node { int c[26], fa, v; char s; } t[NM]; inline void ins(char *s, int id) {
int n = strlen(s + 1), o = 0;
for (int i = 1; i <= n; ++i) {
if (!t[o].c[s[i] - 'A']) t[o].c[s[i] - 'A'] = ++nod, t[nod].s = s[i];
o = t[o].c[s[i] - 'A'];
}
t[o].v |= 1 << (id - 1);
}
inline void build() {
int hd = 0, tl = 0;
for (int i = 0; i < 26; ++i) if (t[0].c[i]) q[++tl] = t[0].c[i];
while (hd < tl) {
int x = q[++hd]; t[x].v |= t[t[x].fa].v;
for (int i = 0; i < 26; ++i)
if (t[x].c[i]) t[t[x].c[i]].fa = t[t[x].fa].c[i], q[++tl] = t[x].c[i];
else t[x].c[i] = t[t[x].fa].c[i];
}
} inline void work() {
int hd = 0, tl = 1, S = (1 << n) - 1;
q[tl] = 0, q2[tl] = 0, fr[0][0] = -1;
while (hd < tl) {
int x = q[++hd];
int s = q2[hd];
// dbg("x = %d, s = %d\n", x, s);
for (int i = 0; i < 26; ++i) if (t[x].c[i]) {
int y = t[x].c[i], ss = s | t[y].v;
// dbg("y = %d, ss = %d\n", y, ss);
if (!fr[y][ss]) {
fr[y][ss] = hd, q[++tl] = y, q2[tl] = ss;
// dbg("****** y = %d, ss = %d\n", y, ss);
if (ss == S) {
int len = 0, z = y, zs = ss, zz;
while (~fr[z][zs]) ans[++len] = t[z].s, zz = fr[z][zs], z = q[zz], zs = q2[zz];
while (len) putchar(ans[len--]);
puts("");
// dbg("*********\n");
return;
}
assert(fr[y][ss]);
}
}
}
} inline void init() {
read(n);
for (int i = 1; i <= n; ++i) scanf("%s", s + 1), ins(s, i);
build();
// dbg("*************\n");
} int main() {
#ifdef hzhkk
freopen("hkk.in", "r", stdin);
#endif
init();
work();
fclose(stdin), fclose(stdout);
return 0;
}

bzoj1195 [HNOI2006]最短母串 AC 自动机+状压+bfs的更多相关文章

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

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

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

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

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

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

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

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

  5. BZOJ1195 [HNOI2006]最短母串 AC自动机 bfs

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 传送门 - BZOJ1195 题意概括 给出一堆串,然后求一个包含这些串的所有串的最短的中的字典序最小的. 题解 先造一个AC ...

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

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

  7. BZOJ 1195 [HNOI2006]最短母串 (Trie图+状压+bfs最短路)

    BZOJ1195 LOJ10061 题目大意:给你$n$个模式串,求一个最短且字典序最小的文本串并输出这个串,$n<=12,len<=50$ 首先对所有模式串构造$Trie$图,$Trie ...

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

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

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

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

随机推荐

  1. np.random.shuffle(x)与np.random.permutation(x)

    来自:https://blog.csdn.net/brucewong0516/article/details/79012233 将数组打乱随机排列 两种方法: np.random.shuffle(x) ...

  2. 前端必须掌握的 nginx 技能(1)

    概述 作为一个前端,我觉得必须要学会使用 nginx 干下面几件事: 代理静态资源 设置反向代理(添加https) 设置缓存 设置 log 部署 smtp 服务 设置 redis 缓存(选) 下面我按 ...

  3. 使用 circleci 自动部署 vuepress 到 github

    概述 今天我想把博客什么的搬到 github 的 vuepress 上面.但是每次提交 md 文件需要手动打包然后再提交到 github 的 gh-pages,非常麻烦.所以我去研究了一下用 circ ...

  4. 测开之路一百四十七:用WTForms实现编辑功能

    接上一篇的内容 把原先的数据库模型全部给默认值,后面form赋值的时候就不用传位置参数了 把视图逻辑修改一下 # 视图层from datetime import datetimefrom flask. ...

  5. framework7 底部弹层popup js关闭方法

    <div class="u-sd-btns"> <button>同意</button> <button class="popup ...

  6. oracle 迁移数据文件

    步骤: 1.SQL>SELECT FILE_NAME FROM DBA_DATA_FILES; FILE_NAME --------------------------------------- ...

  7. 彻底理解RSA算法原理

    1. 什么是RSA RSA算法是现今使用最广泛的公钥密码算法,也是号称地球上最安全的加密算法.在了解RSA算法之前,先熟悉下几个术语 根据密钥的使用方法,可以将密码分为对称密码和公钥密码 对称密码:加 ...

  8. date picker with jquery

    <html> <input id="from_time" name="from_time"type="text" valu ...

  9. Luogu P1315 [NOIP2012]观光公交

    题目 每次把加速器用在可以是答案减少最多的地方就即可.(这不是废话吗?) 具体而言,我们处理出: \(sum_i\)到\(i\)为止下车人数之和. \(t_i\)在\(i\)最晚的上车的人的上车时间. ...

  10. thinkphp整合Ueditor编辑器

    编辑器下载地址:http://ueditor.baidu.com/website/download.html#ueditor 放在项目Public或者入口同级目录均可. 前台代码 <div cl ...