2782: [HNOI2006]最短母串

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 3  Solved: 2
[Submit][Status][Web Board]

Description

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

Input

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

Output

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

Sample Input

2
ABCD
BCDABC

Sample Output

ABCDABC

HINT

 

Source

题解:

  

  首先我的思路十分傻叉,是f[i][j][k]f[i][j][k]表示长度为ii,在自动机上的节点为jj,包含子串的状态为kk可不可能.但这样复杂度直接爆炸.

  但是我们可以令f[i][j]f[i][j]表示在自动机上的节点为ii,包含子串的状态为jj时的最短长度.

  这样我们就转化成了边权均为1的单源最短路,BFS就行了.

  若按照字母字典序从小到大的顺序进行BFS,得出的就是字典序最小的答案了.

  (有点卡内存)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int inf=1e9;
struct Node{
int fail,ch[],val;
void clear(){
fail=val=;
memset(ch,,sizeof(ch));
}
}tr[];
int sz;
int bin[],n;
void insert(char *s,int val){
int u=,len=strlen(s);
for(int i=;i<len;i++){
int c=s[i]-'A';
if(!tr[u].ch[c]){
tr[u].ch[c]=++sz;
tr[sz].clear();
}
u=tr[u].ch[c];
}
tr[u].val|=bin[val];
}
void build(){
queue<int>q;q.push();
while(!q.empty()){
int u=q.front();q.pop();
for(int i=;i<;i++){
if(tr[u].ch[i]){
int v=tr[u].ch[i];
if(u)tr[v].fail=tr[tr[u].fail].ch[i];
q.push(v);
}else tr[u].ch[i]=tr[tr[u].fail].ch[i];
}
}
}
int fromu[][],froms[][];
bool vis[][];
void print(int u,int s){
if(!u)return;
print(fromu[u][s],froms[u][s]);
for(int i=;i<;i++){
int v=tr[fromu[u][s]].ch[i],t=froms[u][s];
for(int p=v;p;p=tr[p].fail)
t|=tr[p].val;
if(v==u&&t==s){
putchar('A'+i);
break;
}
}
}
void bfs(){
queue<int>q1,q2;
q1.push();q2.push();
vis[][]=;
while(!q1.empty()){
int u=q1.front(),s=q2.front();q1.pop();q2.pop();
for(int i=;i<;i++){
int v=tr[u].ch[i],t=s;
for(int p=v;p;p=tr[p].fail)
t|=tr[p].val;
if(!vis[v][t]){
vis[v][t]=;
q1.push(v);q2.push(t);
fromu[v][t]=u;
froms[v][t]=s;
if(t==bin[n+]-){
print(v,t);
return;
}
}
}
}
}
char s[];
int main(){
scanf("%d",&n);
tr[sz=].clear();
bin[]=;
for(int i=;i<;i++)bin[i]=bin[i-]<<;
for(int i=;i<=n;i++){
scanf("%s",s);
insert(s,i);
}
build();
bfs();
return ;
}
 

2782: [HNOI2006]最短母串的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. bzoj 1195 [HNOI2006]最短母串 bfs 状压 最短路 AC自动机

    LINK:最短母串 求母串的问题.不适合SAM. 可以先简化问题 考虑给出的n个字符串不存在包含关系. 那么 那么存在的情况 只可能有 两个字符串拼接起来能表示另外一个字符串 或者某个字符串的后缀可以 ...

随机推荐

  1. 注意:MainActivity的oncreate方法里不要再inflate布局了(MainActivity里的点击事件无响应)

    activity_main已经通过setContentView(R.layout.activity_main);设置给MainActivity, 不要再inflate出新布局,然后findviewby ...

  2. listview的条目(item)如何做出卡片效果

    卡片,其实就是一张背景图片,但做也还需要注意一点. 错误做法: <?xml version="1.0" encoding="utf-8"?> < ...

  3. java+tomcat+Eclipse+mysql配置

    Java下载及配置: 1. 下载:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html ...

  4. 去掉tomcat中appBase默认的ROOT

    我想修改tomcat的项目目录,写成绝对路径后,默认去找ROOT文件夹 怎么去掉呢 <Host name="localhost" appBase="E:\ceshi ...

  5. ST Visual Programmer批量烧写教程

    源:ST Visual Programmer批量烧写教程 参考:为什么STM8 写了保护后,用ST Visual Programmer 无法重新烧录程序? 首先要说下为什么要建立烧写工程呢- -原因只 ...

  6. 转:Windows下用sftp自动下载文件

    远程服务器是Linux操作系统,没有ftp服务,可以ssh,数据库每天2:00会自动创建一个备份文件,本地计算机是windows操作系统,希望用sftp每天3:00下载远程服务器上的备份文件.本地系统 ...

  7. 页面加载完毕执行多个JS函数

    通常我们需要在打开页面时加载脚本,这些脚本必须在页面加载完毕后才可以执行,因为这时候DOM才完整,可以利用window.onload确保这一点,如:window.onload=firstFunctio ...

  8. 修改sqlserver的数据库排序规则语句

    alter database SOETMS collate Chinese_PRC_CI_AS

  9. 原生 JS Ajax,GET和POST 请求实例代码

    javascript/js的ajax的GET请求代码如下所示: <script type="text/javascript"> /* 创建 XMLHttpRequest ...

  10. 使用Java打印杨辉三角

    package 杨辉三角; import java.util.Scanner; public class 三角 { private static Scanner scn; public static ...