P2322 [HNOI2006]最短母串问题

AC自动机+bfs

题目要求:在AC自动机建的Trie图上找到一条最短链,包含所有带结尾标记的点

因为n<12,所以我们可以用二进制保存状态:某个带结尾标记的点是否被处理到。

把编号为 i 的结尾标记设为2^(i-1)

然后跑一遍bfs,如果跑到某个点结尾标记之和=2^n-1,那么就说明答案找到了

开2个数组保存每个bfs状态的对应的上一个编号和对应字母

输出的时候递归即可

attention:保存bfs状态的数组一定要开的很大(2e5/1e6/2e6 70pts/90pts/AC)

对于字典序问题:查找顺序都是'A'->‘Z’,不用担心(我还瞎操心个啥qaq)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct data{
int nxt[],fail,last,end;
}a[];
struct node{int id,t,state;};
char q[];
int n,cnt1,cnt2,pre1[],pre2[];
bool vis[][];
inline void Trie_build(int id){
scanf("%s",q);
int u=,len=strlen(q);
for(int i=;i<len;++i){
int p=q[i]-'A';
if(!a[u].nxt[p]) a[u].nxt[p]=++cnt1;
u=a[u].nxt[p];
}a[u].end|=<<(id-); //标记值=2^(i-1)
}
void AC_build(){
queue <int> h;
for(int i=;i<;++i) if(a[].nxt[i]) h.push(a[].nxt[i]);
while(!h.empty()){
int x=h.front(); h.pop();
for(int i=;i<;++i){
int &to=a[x].nxt[i];
if(to){
a[to].fail=a[a[x].fail].nxt[i];
a[to].last= a[a[to].fail].end ? a[to].fail:a[a[to].fail].last;
a[to].end|=a[a[to].last].end; //累加上所有后缀的状态
h.push(to);
}else to=a[a[x].fail].nxt[i];
}
}
}
inline void print(int x){ //递归输出
if(!x) return;
print(pre1[x]);
putchar(pre2[x]+'A');
}
void bfs(){
queue <node> h;
h.push((node){,,a[].end});
while(!h.empty()){
node x=h.front(); h.pop();
if(x.state==(<<n)-) {print(x.t); return ;}
for(int i=;i<;++i){ //字典序从小到大
node to=(node){a[x.id].nxt[i],,x.state|a[a[x.id].nxt[i]].end}; //状态更新
if(vis[to.state][to.id]) continue; //去重
vis[to.state][to.id]=; to.t=++cnt2; //给一个新编号
pre1[cnt2]=x.t; pre2[cnt2]=i; //用两个数组存该编号对应的字母和上级的编号
h.push(to);
}
}
}
int main(){
scanf("%d",&n);
for(int i=;i<=n;++i) Trie_build(i);
AC_build(); bfs();
return ;
}

P2322 [HNOI2006]最短母串问题的更多相关文章

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

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

  2. 2782: [HNOI2006]最短母串

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

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

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

  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. HOJ 2985 Wavio Sequence(最长递增子序列以及其O(n*logn)算法)

    Wavio Sequence My Tags (Edit) Source : UVA Time limit : 1 sec Memory limit : 32 M Submitted : 296, A ...

  2. windows远程访问ubuntu下的jupyter notebook必要配置

    0.生成配置文件(一般采用默认) jupyter notebook --generate-config 1.打开ipython, 创建一个密文密码 In [1]: from notebook.auth ...

  3. Java编程思想中关于闭包的一个例子

    Java编程思想中的一个例子,不是很理解使用闭包的必要性,如果不使用闭包,是不是有些任务就不能完成?继续探索. package InnerClass; interface Incrementable ...

  4. Google词向量word2vec的使用

    """ 1.在自然语言处理中常常使用预训练的word2vec,这个预训练的词向量可以使用google的GoogleNews-vectors-negative300.bin ...

  5. easyui-datagrid个人实例

    这个实例数据表格的功能,可以实现分页,增删改查功能 1.user.jsp <%@ page language="java" contentType="text/ht ...

  6. Oracle管理监控之设置linux启动时自动启动oracle服务器

    1. 修改dbstart脚本(第78行):$ vi $ORACLE_HOME/bin/dbstartORACLE_HOME_LISTNER=$ORACLE_HOME 2. 修改/etc/oratab为 ...

  7. date 命令之日期和秒数转换

    时间转为秒数 date -d "2012-11-12 13:00:00" +"%s" 描述转为日期 date -d@1352692800 +"%Y-% ...

  8. PHP AOP编程思想

    AOP思想(面向切面编程) 在应用开发中,我们经常发现需要很多功能,这些功能需要经常被分散在代码中的多个点上,但是这些点事实上跟实际业务没有任何关联.比如,在执行一些特殊任务之前需要确保用户是在登陆状 ...

  9. 冒泡排序快速版(C)

    冒泡排序C语言版:在每轮排序中检查时候有元素位置交换,如果无交换,说明数组元素已经有序,无需继续排序 #include <stdio.h> #include <stdlib.h> ...

  10. mysql 使用存储引擎

    三 使用存储引擎 方法1:建表时指定引擎 指定innodb,不写默认也是innodb use 数据库先 create table innodb_t1(id int,name char)engine=i ...