题面:洛谷

题解:

  如果我们对这些小串建出AC自动机,那么我们所求的大串就是要求满足遍历过所有AC自动机上的叶子节点,且经过步数最少的串。如果有多个步数相同的串,要输出字典序最小的串。

  在AC自动机上DP。

  因为我们要求所求串内要出现所有给定小串,而小串个数较少,因此我们考虑状压,然后保存下val[i]表示走到这个点,就可以拥有哪些子串。因为一个非终止节点也可能包含给定小串,因此我们要在建好fail之后,继承一个点x的fail[x]所包含的小串,按编号大小更新即可保证在x被更新之前fail[x]已经被更新。

  设f[i][j]表示在AC自动机的第i个节点上,状态为j的最小代价。

  不知你是否注意到这个状态里没有限制长度和字典序?

  其实这是因为我们可以用bfs解决问题,因为走任意一步的代价都是1,也就是每条边的权值都是1,所以如果我们用bfs的顺序来DP,那么谁先DP到拥有所有串,谁就是代价最小的方案。

  那么怎么保证字典序最小?

  我们只需要在bfs的时候从'a'开始枚举即可。

  

 #include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 610
#define ac 4596
#define inf 2139062143 int n, m, maxn, tmp, head, tail;
int f[AC][ac], q1[AC * ac], q2[AC * ac];
short l1[AC][ac], l2[AC][ac];
int c[AC][], val[AC], fail[AC], go[AC], tot;
char s[AC]; inline void add()
{
int len = strlen(s + ), now = ;
for(R i = ; i <= len; i ++)
{
int v = s[i] - 'A';
if(!c[now][v]) c[now][v] = ++ tot, go[tot] = v;
now = c[now][v];
}
val[now] |= tmp, tmp <<= ;//还是要|= 的,否则要是有多个相同串在同一个节点结束就不好了,,,,
} #define q q1
void build()
{
for(R i = ; i < ; i ++)
if(c[][i]) q[++ tail] = c[][i];
while(head < tail)
{
int x = q[++ head];
for(R i = ; i < ; i ++)
{
if(c[x][i]) fail[c[x][i]] = c[fail[x]][i], q[++ tail] = c[x][i];
else c[x][i] = c[fail[x]][i];
}
}
for(R i = ; i <= tot; i ++) val[i] |= val[fail[i]];
}
#undef q void pre()
{
scanf("%d", &n);
maxn = ( << n) - , tmp = ;
memset(f, , sizeof(f));
for(R i = ; i <= n; i ++) scanf("%s", s + ), add();
} void bfs()
{
head = tail = ;
q1[++ tail] = , q2[tail] = ;
f[][] = ;
while(head < tail)
{
int x = q1[++ head], sta = q2[head];
if(sta == maxn)
{
head = ;
while(x)
{
q1[++ head] = go[x];
int tmp1 = x, tmp2 = sta;
x = l1[tmp1][tmp2], sta = l2[tmp1][tmp2];
}//因为要用2次,但是用了第一次之后x or sta就改变了,所以必须保存到临时变量
for(R i = head; i; i --) printf("%c", q1[i] + 'A');
return ;
}
for(R i = ; i < ; i ++)
{
int v = c[x][i], w = sta | val[v];
if(f[v][w] == inf) //bfs包括了最短和字典序最小
{
q1[++ tail] = v, q2[tail] = w;
f[v][w] = f[x][sta] + ;
l1[v][w] = x, l2[v][w] = sta;
}
}
}
} int main()
{
// freopen("in.in", "r", stdin);
pre();
build();
bfs();
// fclose(stdin);
return ;
}

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

  1. [HNOI2006]最短母串问题 --- AC自动机 + 隐式图搜索

    [HNOI2006]最短母串问题 题目描述: 给定n个字符串(S1,S2.....,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,......,Sn)都是T的子串. 输入格式: 第 ...

  2. [BZOJ1195]:[HNOI2006]最短母串(AC自动机+BFS)

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

  3. [HNOI2006]最短母串问题——AC自动机+状压+bfs环形处理

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

  4. P2322 [HNOI2006]最短母串问题

    P2322 [HNOI2006]最短母串问题 AC自动机+bfs 题目要求:在AC自动机建的Trie图上找到一条最短链,包含所有带结尾标记的点 因为n<12,所以我们可以用二进制保存状态:某个带 ...

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

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

  6. 【状态压缩dp】1195: [HNOI2006]最短母串

    一个清晰的思路就是状压dp:不过也有AC自动机+BFS的做法 Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T ...

  7. bzoj 1195: [HNOI2006]最短母串 爆搜

    1195: [HNOI2006]最短母串 Time Limit: 10 Sec  Memory Limit: 32 MBSubmit: 894  Solved: 288[Submit][Status] ...

  8. 2782: [HNOI2006]最短母串

    2782: [HNOI2006]最短母串 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 3  Solved: 2[Submit][Status][Web ...

  9. BZOJ 1195: [HNOI2006]最短母串

    1195: [HNOI2006]最短母串 Time Limit: 10 Sec  Memory Limit: 32 MBSubmit: 1346  Solved: 450[Submit][Status ...

随机推荐

  1. 电信NB-IOT的温湿度采集器开发记录

    1. 首先打开浏览器,登录电信商用服务器,上传profile文件 2. 上传编解码插件在,注意的是,上传编解码插件是电信测试用服务器平台(不同的网址),反正不明白电信搞啥幺蛾子,得两个地方去上传 3. ...

  2. java nio实现文件复制

    public class TransferTo { public static void main(String[] args) throws Exception { FileChannel in = ...

  3. PHASER3 设置场景SCENE SLEEPING休眠和WAKE唤醒

    A good way to set scene stop when hidden and run while visible again ! 使用sleep和wake方法的好处: 1.可以彻底让sce ...

  4. Spring Cloud(三):服务提供与调用 Eureka【Finchley 版】

    Spring Cloud(三):服务提供与调用 Eureka[Finchley 版]  发表于 2018-04-15 |  更新于 2018-05-07 |  上一篇文章我们介绍了 Eureka 服务 ...

  5. Amazon移除差评适用范围 - Amazon request for the feedback removal

    Greetings from Amazon Seller Support, Please accept my sincere apologies for the inconvenience cause ...

  6. Coin Game

    Problem Description After hh has learned how to play Nim game, he begins to try another coin game wh ...

  7. Thunder--Beta发布--美工+文案

    作业:https://edu.cnblogs.com/campus/nenu/SWE2017FALL/homework/1366 内容: 美工:原有功能展示.新增功能展示 程序图标 欢迎页面 我的书架 ...

  8. 20172326『Java程序设计』课程结对编程练习_四则运算第二周阶段总结

    20172326『Java程序设计』课程结对编程练习_四则运算第二周阶段总结 小组成员 20172313 余坤澎 20172332 于欣月 20172326 康皓越 小组编程照片 设计思路 通过一个E ...

  9. python 二维矩阵及转byte知识点

    1.注意python中的数组和list形式混合: 数组在numpy里面: 2.二维数组这样定义可以修改固定位置的值: rawDataArray_temp = [([0]*nIRImageWidth)f ...

  10. CodeForces 154A Hometask dp

    题目链接: http://codeforces.com/problemset/problem/154/A 题意: 给你一个字符串,和若干模板串(长度为2),至少删除多少个字母,使得字符串的字串里面没有 ...