题目传送门

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. React Native商城项目实战05 - 设置首页的导航条

    1.Home.js /** * 首页 */ import React, { Component } from 'react'; import { AppRegistry, StyleSheet, Te ...

  2. leetcode-easy-array-283 move zeros

    mycode  77.24% class Solution(object): def moveZeroes(self, nums): """ :type nums: Li ...

  3. 现有1~100 共一百个自然数,已随机放入一个有98个元素的数组a[98].要求写出一个尽量简单的方案找出没有被放入数组的那2个数,并在屏幕上打印这2个数

    void test7() { try { ]; ]; ]; ; ; int i; ; i < num.Length; i++) { num[i] = i + ; num1[i] = i + ;/ ...

  4. 网页上预览pdf文件的几种方案

    网页上查看pdf的方案: 1.使用adobe reader的插件 2.使用在线office控件 3.使用火狐开源项目pdf.js(浏览器需支持html5) 4.将pdf转换为swf文件 5.使用pdf ...

  5. LeetCode算法题-Magic Squares In Grid(Java实现)

    这是悦乐书的第326次更新,第349篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第196题(顺位题号是840).3 x 3魔方是一个3 x 3网格,填充了从1到9的不同 ...

  6. 梳理检测论文-Refinement Neural Network

    Single-Shot Refinement Neural Network for Object Detection 目录 1. motivation 2. RefineDet 解析(Network ...

  7. 【Linux开发】./configure,make,make install的作用

    这些都是典型的使用GNU的AUTOCONF和AUTOMAKE产生的程序的安装步骤. ./configure是用来检测你的安装平台的目标特征的.比如它会检测你是不是有CC或GCC,并不是需要CC或GCC ...

  8. 【Qt开发】Linux下Qt开发环境的安装与集成

    近期工作需要在Linux下用Qt进行C++开发,所以就在linux下尝试装QT开发环境.本人用的linux是CentOS 6.5.现在对安装过程做出总结.有两种安装方式,下面分别详述: 1 图形化安装 ...

  9. java基础/java调用shell命令和脚本

    一.项目需求: 从某一机构获取证书,证书机构提供小工具,执行.sh脚本即可启动服务,本地调用该服务即可获取证书. 问题:linux服务器启动该服务,不能关闭.一旦关闭,服务即停止. 解决方案:java ...

  10. 简述Vue的实例属性、实例方法

    1.实例属性 组件树访问 $parent -----> 用来访问当前组件实例的父实例: $root -----> 用来访问当前组件树的根实例,如果当前组件没有父实例,则$root表示当前组 ...