题目传送门


题目描述

给定n个字符串(S1,S2,…,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,…,Sn)都是T的子串。


输入格式

第一行是一个正整数n,表示给定的字符串的个数。
以下的n行,每行有一个全由大写字母组成的字符串。每个字符串的长度不超过50。

输出格式

只有一行,为找到的最短的字符串T。在保证最短的前提下,
如果有多个字符串都满足要求,那么必须输出按字典序排列的第一个。

样例

样例输入:
2
ABCD
BCDABC
样例输出:
ABCDABC

数据范围与提示

对于全部数据,1≤n≤12,1≤|Si|≤50。

题解

一看是多模式串,首先应该想到是AC自动机。

如果还不会AC自动机,可以转到这篇博客,个人感觉还是写的挺清楚的:AC自动机讲解+[HDU2222]:Keywords Search(AC自动机)

那么我们考虑怎么去处理。

看到n的取值范围之后,我们可以考虑状态压缩。
然后,要求串最短,且字典序最小,那么可以考虑BFS从跟节点开始,每个状态A->Z爆搜,那么这样的话就可以保证当前搜到的串。
统计答案时从最后一个点往前找即可。

代码时刻

#include<bits/stdc++.h>
using namespace std;
int trie[5000][5000],cnt=1,ed[5000],nxt[5000];
char s[50];
int que[5000],que1[10000000],que2[10000000],que3[10000000],que4[10000000];
//que用于求Fail指针
//que1-4用于BFS,que1用于存储答案,que2用于存储上一个点在队列中的位置,que3用与存储当前点的编号,que4用于存储状态
bool vis[5000][5000];
int tot;
int n;
int ans[5000];
void insert(char *str,int id)//依然建树
{
int len=strlen(str);
int p=1;
for(int i=0;i<len;i++)
{
int ch=str[i]-'A';
if(!trie[p][ch])trie[p][ch]=++cnt;
p=trie[p][ch];
}
ed[p]|=1<<(id-1);
}
void build()//找Fail指针
{
for(int i=0;i<26;i++)trie[0][i]=1;
que[1]=1;
int head=1,tail=1;
while(head<=tail)
{
for(int i=0;i<26;i++)
{
if(!trie[que[head]][i])trie[que[head]][i]=trie[nxt[que[head]]][i];
else
{
que[++tail]=trie[que[head]][i];
nxt[trie[que[head]][i]]=trie[nxt[que[head]]][i];
ed[trie[que[head]][i]]|=ed[trie[nxt[que[head]]][i]];
}
}
head++;
}
}
void ask()//BFS
{
int head=1,tail=1;
int end=(1<<n)-1;
que3[1]=1;
while(head<=tail)
{
if(que4[head]==end)
{
while(head>1)
{
ans[++tot]=que1[head];
head=que2[head];
}
while(tot--)printf("%c",ans[tot+1]+'A');
return;
}
for(int i=0;i<26;i++)
if(!vis[trie[que3[head]][i]][que4[head]|ed[trie[que3[head]][i]]])//用vis存储当前状态有没有被访问过
{
que1[++tail]=i;//添加这个点
que2[tail]=head;//存储上一个点
que3[tail]=trie[que3[head]][i];//存储当前点的编号
que4[tail]=que4[head]|ed[trie[que3[head]][i]];//存储状态
vis[trie[que3[head]][i]][que4[head]|ed[trie[que3[head]][i]]]=1;//表示当前状态已经被访问过
}
head++;
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",s);
insert(s,i);
}
build();
ask();
return 0;
}

rp++

[BZOJ1195]:[HNOI2006]最短母串(AC自动机+BFS)的更多相关文章

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

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

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

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

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

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

  4. bzoj1195 [HNOI2006]最短母串 AC 自动机+状压+bfs

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1195 题解 建立 AC 自动机,然后构建出 trie 图. 然后直接在 trie 图上走.但是 ...

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

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

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

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

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

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

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

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

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

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

  10. Bzoj1195 [HNOI2006]最短母串 [状态压缩]

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

随机推荐

  1. C++:string操作函数

    要想使用标准C++中string类,必须要包含 #include <string>// 注意是<string>,不是<string.h>,带.h的是C语言中的头文件 ...

  2. C语言--- 高级指针2(结构体指针,数组作为函数参数)

    一.结构体指针 1. 什么是结构体指针?指向结构体变量的指针     结构体:     typedef  struct stu{                          char name[ ...

  3. Django查询数据库返回字典dict数据

    个人观点: 个人认为,在Django项目中, 开发团队为了让使用该框架的用户都使用自带的序列化功能,从而让框架中的SQL返回值很不直观,对于直接使用SQL语句的用户很犯难. 解决: from djan ...

  4. 【golang】浅析rune数据类型

    golang中string底层是通过byte数组实现的.中文字符在unicode下占2个字节,在utf-8编码下占3个字节,而golang默认编码正好是utf-8. golang中还有一个byte数据 ...

  5. 3D max导出的设置选项

    一3D max导出的设置选项

  6. 微信小程序自定义字体及自定义图标问题说明

    自定义图标及自定义字体,一直是很多小程序开发者的心病,其实本站是很多解决方案的,为了集中起来,方便直接跳过此坑,我特别做了这次针对字体及字体图标的跳坑: 相关文章:微信小程序添加并使用外部字体(成功添 ...

  7. python-函数1(定义-作用-优势-返回值)

    python-函数1(定义-作用-优势-返回值) 1.面向对象的定义是靠-类>>class2.面向过程的定义是靠-过程 >>def3.函数式编程的定义是靠-函数>> ...

  8. nginx的简单介绍

    nginx简单介绍 Nginx的负载均衡策略可以分两大类:内置策略和扩展侧略: 内置策略包括:轮询,加权轮询,IP hash 扩展策略是:url hash ,fair nginx.conf文件结构 1 ...

  9. 百度贴吧自动回帖的两种方式,使用requests(urllib2)和selenium两种方式回帖

    本文介绍,回复贴吧指定某楼层主的帖子的方法.在这里不介绍无限发主贴和无限回复主贴的方法,无限发主题帖会爆吧,引起别人的反感,并且很容易遭到吧主的封杀:无限回主题帖,会让整个帖子的每楼的回复充满了自己的 ...

  10. SpringFramework中的BeanWrapper丶PropertyEditor

    BeanWrapper是org.springframework.beans包下的一个借口,对应的实现类为BeanWrapperImpl,提供对应的get/set方法,并且设置属性的可读性和可写性. p ...