题目传送门

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. java利用zip解压slpk文件

    public static void main(String[] args) { File file = new File("C:\\Users\\Administrator\\Deskto ...

  2. 基于Python对象引用、可变性和垃圾回收详解

    基于Python对象引用.可变性和垃圾回收详解 下面小编就为大家带来一篇基于Python对象引用.可变性和垃圾回收详解.小编觉得挺不错的,现在就分享给大家,也给大家做个参考. 变量不是盒子 在示例所示 ...

  3. dotnet core排序异常,本地测试和linux上结果不一致

    根据汉字排序,本地测试结构正常,发到docker之后,发现汉字升序降序和本地相反,检查代码后,没找到任何可能出现问题的点. 然后去翻文档:字符串比较操作 看到了这一句,会区分区域性 然后猜测应该是do ...

  4. Discrete Mathematics and Its Applications | 1 CHAPTER The Foundations: Logic and Proofs | 1.2 Applications of Propositional Logic

    Translating English Sentences System Specifications Boolean Searches Logic Puzzles Logic Circuits

  5. 【Linux U-boot】U-Boot相关命令

    <1> help --帮助命令环境变量相关: <2> printenv --查看环境变量也可以使用缩写:print 查看某一个环境变量的值,例子:printenv bootar ...

  6. XLS导出的服务器端配置方式

    IIS支持excel导出: 1.开始—运行,然后键入DCOMCNFG; 2.组件服务—计算机—我的电脑—DCOM配置,这时弹出一个问注册的窗口,确定注册. 这时如果一切恢复正常了,不用往下操作了. 关 ...

  7. [集合]Map

      Map集合的功能概述 a:添加功能 * V put(K key,V value):添加元素.* 如果键是第一次存储,就直接存储元素,返回null * 如果键不是第一次存在,就用值把以前的值替换掉, ...

  8. tensorflow学习笔记六----------神经网络

    使用mnist数据集进行神经网络的构建 import numpy as np import tensorflow as tf import matplotlib.pyplot as plt from ...

  9. vue生命周期简单总结

    生命周期(钩子函数):一个组件从创建到销毁的过程就是生命周期     beforeCreate: 创建前     1.当前vue实例化的时候会做一个初始化的操作,在这个生命周期函数中我们可以做初始化的 ...

  10. 梯度下降算法(Gradient descent)GD

    1.我们之前已经定义了代价函数J,可以将代价函数J最小化的方法,梯度下降是最常用的算法,它不仅仅用在线性回归上,还被应用在机器学习的众多领域中,在后续的课程中,我们将使用梯度下降算法最小化其他函数,而 ...