题面:洛谷

题解:

  如果我们对这些小串建出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. Session丢失——解决方案

    先抄下别人的作业(原帖:http://www.cnblogs.com/zhc088/archive/2011/07/24/2115497.html) Session丢失已经是一种习以为常的问题了,在自 ...

  2. Lambada表达式的作用

    Lambda函数的用处   假设你设计了一个地址簿的类.现在你要提供函数查询这个地址簿,可能根据姓名查询,可能根据地址查询,还有可能两者结合.要是你为这些情况都写个函数,那么你一定就跪了.所以你应该提 ...

  3. JS基础,课堂作业,成绩练习

    成绩练习 <script> var name = prompt("请输入学生姓名:"); var degree = parseInt(prompt("请输入学 ...

  4. div不设置高度背景颜色或外边框不能显示的解决方法

    在使用div+css进行网页布局时,如果外部div有背景颜色或者边框,而不设置其高度,在浏览时出现最外层Div的背景颜色和边框不起作用的问题. 大体结构<div class="oute ...

  5. TCP/IP三次握手四次挥手分析

    流程图 全部11种状态 客户端独有的:(1)SYN_SENT (2)FIN_WAIT1 (3)FIN_WAIT2 (4)CLOSING (5)TIME_WAIT 服务器独有的:(1)LISTEN (2 ...

  6. 《图解 HTTP 》阅读 —— 第二章

    第2章 简单的http协议 http 协议用于客户端和服务器端的通信. 请求访问文本或图像等资源的一端称为客户端,提供资源响应的一端称为服务器端. 请求报文: 响应报文: 为了能够处理大量的事务,ht ...

  7. Bellman-ford 模板

    #include<bits/stdc++.h> const int inf=0x3f3f3f3f; ; struct edge{ int u,v;//两个点 int w; //权值 Edg ...

  8. Kubernetes学习-相关概念

    Kubernetes架构图 上图可以看到如下组件,使用特别的图标表示Service和Label: Pod Container(容器) Label()(标签) Replication Controlle ...

  9. Kubernetes v1.10----部署kubernetes-dashboard v1.83

    Kubernetes v1.10----部署kubernetes-dashboard v1.83 1.下载 kubernetes-dashboard  yaml文件 #因为文件中的image指定的是谷 ...

  10. 从零开始的Python学习Episode 13——常用模块

    模块 一.time模块 时间戳(timestamp) :时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量. 元组(struct_time)   :struct_time元组共有9 ...