【loj10061】最短母串
题目描述
原题来自:HNOI 2006
给定 n个字符串 S1,S2,⋯,Sn 要求找到一个最短的字符串 T,使得这 n 个字符串都是 T 的子串。
输入格式
第一行是一个正整数 n,表示给定的字符串的个数;
以下的 n 行,每行有一个全由大写字母组成的字符串。
输出格式
只有一行,为找到的最短的字符串 T。
在保证最短的前提下,如果有多个字符串都满足要求,那么必须输出按字典序排列的第一个。
样例
样例输入
2
ABCD
BCDABC
样例输出
ABCDABC
数据范围与提示
对于全部数据,1≤n≤12,1≤∣Si∣≤50。
题意:(挂loj是因为我的解法在bzoj上T了并且我不想调QAQ)
给你$n$个字符串,求他们的最短母串,即求一个最短字符串使得这$n$个字符串都是它的子串。若长度相同输出字典序最小的。
题解:
建出$AC$自动机后问题转化成找一条最短的路径覆盖所有$end$节点。
那么我们可以考虑对每个节点维护一个压缩状态表示从根走到该点包含了哪些字符串。
然后从根开始沿$bfs$序遍历(保证字典序最小)并记录路径,若合法则输出答案。
这题主要是教会了我一个真理:
当你发现某个代码已经改不出来的时候,重构代码总是会给你惊喜……
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue> using namespace std;
#define MAXN 15
#define MAXM 605
#define ll long long struct node{
int son[],s;
}tree[MAXM];
struct way{
int las; char ch;
}p[MAXM*(<<MAXN)];
int tot=,nxt[MAXM];
bool vis[MAXM][<<MAXN];
char str[MAXN],ans[MAXN];
inline int read(){
int x=,f=;
char c=getchar();
for(;!isdigit(c);c=getchar())
if(c=='-')
f=-;
for(;isdigit(c);c=getchar())
x=x*+c-'';
return x*f;
} inline void add(int p,char *str){
int N=strlen(str),u=;
for(int i=;i<N;i++){
int ch=str[i]-'A';
if(!tree[u].son[ch])
tree[u].son[ch]=++tot;
u=tree[u].son[ch];
}
tree[u].s|=(<<p);
return;
} inline void get_nxt(){
for(int i=;i<;i++)
tree[].son[i]=;
queue<int> q; q.push();
while(!q.empty()){
int u=q.front(); q.pop();
for(int i=;i<;i++){
if(tree[u].son[i]){
q.push(tree[u].son[i]);
nxt[tree[u].son[i]]=tree[nxt[u]].son[i];
tree[tree[u].son[i]].s|=tree[tree[nxt[u]].son[i]].s;
}
else tree[u].son[i]=tree[nxt[u]].son[i];
}
}
return;
} inline void solve(int N){
int end=(<<N)-;
queue<int> q1,q2;
q1.push(); q2.push();
int hd=,tl=;
while(!q1.empty() && !q2.empty()){
int u=q1.front();q1.pop();
int sta=q2.front();q2.pop();
if(sta==end){
int cnt=;
for(;hd>;hd=p[hd].las)
ans[++cnt]=p[hd].ch;
for(int i=cnt;i>=;i--)
printf("%c",ans[i]);
printf("\n");
return;
}
for(int i=;i<;i++){
if(!vis[tree[u].son[i]][(tree[tree[u].son[i]].s)|(sta)]){
vis[tree[u].son[i]][(tree[tree[u].son[i]].s)|(sta)]=;
q1.push(tree[u].son[i]);
q2.push((tree[tree[u].son[i]].s)|(sta));
p[++tl].las=hd,p[tl].ch=i+'A';
}
}
hd++;
}
return;
} int main(){
int N=read();
for(int i=;i<N;i++)
scanf("%s",str),add(i,str);
get_nxt(); solve(N);
return ;
}
【loj10061】最短母串的更多相关文章
- bzoj 1195: [HNOI2006]最短母串 爆搜
1195: [HNOI2006]最短母串 Time Limit: 10 Sec Memory Limit: 32 MBSubmit: 894 Solved: 288[Submit][Status] ...
- 2782: [HNOI2006]最短母串
2782: [HNOI2006]最短母串 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 3 Solved: 2[Submit][Status][Web ...
- BZOJ1195[HNOI2006]最短母串——AC自动机+BFS+状态压缩
题目描述 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. 输入 第一行是一个正整数n(n<=12),表示给定的字符串的 ...
- BZOJ 1195: [HNOI2006]最短母串
1195: [HNOI2006]最短母串 Time Limit: 10 Sec Memory Limit: 32 MBSubmit: 1346 Solved: 450[Submit][Status ...
- P2322 [HNOI2006]最短母串问题
P2322 [HNOI2006]最短母串问题 AC自动机+bfs 题目要求:在AC自动机建的Trie图上找到一条最短链,包含所有带结尾标记的点 因为n<12,所以我们可以用二进制保存状态:某个带 ...
- [BZOJ1195]最短母串
1195: [HNOI2006]最短母串 Time Limit: 10 Sec Memory Limit: 32 MB Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最 ...
- [HNOI2006]最短母串问题 --- AC自动机 + 隐式图搜索
[HNOI2006]最短母串问题 题目描述: 给定n个字符串(S1,S2.....,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,......,Sn)都是T的子串. 输入格式: 第 ...
- 【状态压缩dp】1195: [HNOI2006]最短母串
一个清晰的思路就是状压dp:不过也有AC自动机+BFS的做法 Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T ...
- BZOJ_1195_[HNOI2006]最短母串_AC自动机+BFS+分层图
BZOJ_1195_[HNOI2006]最短母串_AC自动机+BFS+分层图 Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2, ...
随机推荐
- appium-java-api
AppiumDriver getAppStrings() 默认系统语言对应的Strings.xml文件内的数据. driver.getAppStrings(String language) 查找某一个 ...
- Phoenix put the sql back in NoSql
Overview | Apache Phoenix http://phoenix.apache.org/index.html Apache Phoenix enables OLTP and opera ...
- 浏览器上的Qt Quick
你想不想在浏览器上运行你的Qt Quick程序呢?在Qt 5.12之前,唯一的方法是使用Qt WebGL Streaming技术把界面镜像到浏览器上.但该方法有不少缺陷,下文会说.前不久随着Qt 5. ...
- GUI界面资源
30个真棒的(免费iPhone,iPad IOS)的GUI 界面设计元素模板 做iphone开发的福音 创造力是指任何一种演示设计i的能力.无论是一个标志,旗帜,广告或一个完整的设计,能够注入的创 ...
- SpringMVC配置环境中一般用的jar包
配置SpringMVC需要把这些jar包加入lib目录下 下载地址,复制到地址栏.回车即可下载 http://files.cnblogs.com/files/QW-lzm/SpringMVC----. ...
- Android API中的对话框
Android API中提供了四个Dialog的自定义子类: AlertDialog ProgressDialog DatePackerDialog TimePickerDialog 也可以派生出自己 ...
- 安装YouCompleteMe时,编译依赖的python版本不对
启动vim打开文件时出错: The ycmd server SHUT DOWN (restart with ':YcmRestartServer'). YCM core library compile ...
- 预处理指令#pragram
#pragma介绍 #pragma是一个预处理指令,pragma的中文意思是『编译指示』.它不是Objective-C中独有的东西(貌似在C/C++中使用比较多),最开始的设计初衷是为了保证代码在不同 ...
- [ZJOI 2008] 骑士
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1040 [算法] 首先 , 题目中互相讨厌的关系构成了一棵基环森林 用拓扑排序找出环 ...
- 【Codeforces 582A】 GCD Table
[题目链接] 点击打开链接 [算法] G中最大的数一定也是a中最大的数. G中次大的数一定也是a中次大的数. 第三.第四可能是由最大和次大的gcd产生的 那么就不难想到下面的算法: ...