原文地址:http://www.cnblogs.com/GXZlegend/p/6825226.html


题目描述

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

输入

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

输出

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

样例输入

2
ABCD
BCDABC

样例输出

ABCDABC


题解

AC自动机+BFS

先求出fail数组和Trie图,同时标记每个位置是哪些字符串的结尾,用二进制储存。

要求包含所有串的最小长度,需要记录当前包含哪些串,需要状压。

当到达字符串结尾时,更改状态。

所以Trie图可以看成一个分层图,所求为0,1到(1<<n)-1,i的最短路。

由于每条路径代表一个字符,所以边权为1,可以使用BFS求最短路得解。

#include <cstdio>
#include <cstring>
char str[60] , ch[610] , ans[610];
int tot = 1 , next[610][26] , fail[610] , val[610] , qx[1500010] , qy[1500010] , l , r , dis[610][4096] , fromp[610][4096];
void build()
{
int x , i;
for(i = 0 ; i < 26 ; i ++ ) next[0][i] = 1;
l = r = 1 , qx[1] = 1;
while(l <= r)
{
x = qx[l ++ ];
for(i = 0 ; i < 26 ; i ++ )
{
if(next[x][i])
fail[next[x][i]] = next[fail[x]][i] , val[next[x][i]] |= val[fail[next[x][i]]] , qx[++r] = next[x][i];
else next[x][i] = next[fail[x]][i];
}
}
}
int main()
{
int n , l , i , j , x , y;
scanf("%d" , &n);
for(i = 1 ; i <= n ; i ++ )
{
scanf("%s" , str + 1) , l = strlen(str + 1) , x = 1;
for(j = 1 ; j <= l ; j ++ )
{
if(!next[x][str[j] - 'A']) next[x][str[j] - 'A'] = ++tot;
x = next[x][str[j] - 'A'] , ch[x] = str[j];
}
val[x] |= 1 << (i - 1);
}
build();
memset(dis , -1 , sizeof(dis));
l = r = 1 , qx[1] = 1 , qy[1] = 0 , dis[1][0] = 0;
while(l <= r)
{
x = qx[l] , y = qy[l];
for(i = 0 ; i < 26 ; i ++ )
{
int tx = next[x][i] , ty = y | val[tx];
if(dis[tx][ty] == -1)
{
dis[tx][ty] = dis[x][y] + 1 , fromp[tx][ty] = l;
if(ty == (1 << n) - 1)
{
int px = tx , py = ty , tmp;
for(i = dis[tx][ty] ; i ; i -- )
ans[i] = ch[px] , tmp = fromp[px][py] , px = qx[tmp] , py = qy[tmp];
printf("%s\n" , ans + 1);
return 0;
}
qx[++r] = tx , qy[r] = ty;
}
}
l ++ ;
}
return 0;
}

【bzoj1195】[HNOI2006]最短母串 AC自动机+状态压缩+BFS最短路的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. BZOJ 1195 [HNOI2006]最短母串 (Trie图+状压+bfs最短路)

    BZOJ1195 LOJ10061 题目大意:给你$n$个模式串,求一个最短且字典序最小的文本串并输出这个串,$n<=12,len<=50$ 首先对所有模式串构造$Trie$图,$Trie ...

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

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

  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. scrollHeight, scrollTop, clientHeight

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. 微信H5单页面滑动的时候如何避免出界,出现头部和底部的黑底?

    ios系统微信浏览器.safari浏览器中h5页面上拉下滑导致悬浮层脱离窗口的解决方法 ios偶现下拉出现黑底时,界面第一次上拉时拉不动的解决方案: document.querySelector('# ...

  3. android design 新控件

    转载请标明出处: http://blog.csdn.net/forezp/article/details/51873137 本文出自方志朋的博客 最近在研究android 开发的新控件,包括drawe ...

  4. javascript入门笔记3-dom

    1.通过ID获取元素 document.getElementById("id") <!DOCTYPE HTML> <html> <head> & ...

  5. poj_1845_Sumdiv

    Consider two natural numbers A and B. Let S be the sum of all natural divisors of A^B. Determine S m ...

  6. JS - 给数组的原型添加去掉重复元素的distinct方法

    /* 调用完该方法,原数组只留下非重复的数据 返回一个数组,里面是依次出现的重复元素 */Array.prototype.distinct = function () {    var removeA ...

  7. datatable 单元格默认文本

    在列字段中添加属性:"defaultContent": "-"

  8. 侯捷《C++面向对象开发》——动手实现自己的复数类

    前言 最近在看侯捷的一套课程<C++面向对象开发>,刚看完第一节introduction之后就被疯狂圈粉.感觉侯捷所提及所重视的部分也正是我一知半解的知识盲区,我之前也写过一些C++面向对 ...

  9. ethereum(以太坊)(十)--函数修饰符

    pragma solidity ^0.4.0; contract modifierTest{ uint public v1; uint constant v2 =10; //uint constant ...

  10. ubuntu安装tomcat7

    1. 下载apache-tomcat-7.0.64.tar.gz 进入tomcat官网:http://tomcat.apache.org/download-70.cgi下载相应的压缩包: 2. 上传安 ...