BZOJ 1195 [HNOI2006]最短母串 (Trie图+状压+bfs最短路)
题目大意:给你$n$个模式串,求一个最短且字典序最小的文本串并输出这个串,$n<=12,len<=50$
首先对所有模式串构造$Trie$图,$Trie$图的性质和$DP$的性质简直是完美契合..
模式串数量很少,考虑状压
定义$f[x][s]$表示现在所在$Trie$图内的位置为$x$,已经匹配到的串的状态为$s$,此时需要文本串的最短长度
转移十分显然,$f[fail_{x}][s|ed[fail_{x}])]=min(f[x][s])+1$
最后找出最小的$f[x][(1<<n)-1]$
然而...直接这样转移我们没办法统计答案啊
考虑把问题放到图上,利用$bfs$队列先进先出的性质,如果我们优先把字典序小的状态推进队列,再通过记录当前状态第一次被更新时的上一层状态$fa[..]$的方式记录路径,跑$bfs$最短路,当队列中出现$s==(1<<n)-1$时立即结束,此时我们求得的一定是长度最短且字典序最小的答案!
注意可能有相同的串
注意不要忘了建$fail$树,如果某个节点是某个串的结尾,也要把它是这个串的结尾的信息传递到它在$fail$树中的子树中去!我没传竟然还有70分
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define NN 610
#define MM 4100
#define ll long long
#define uint unsigned int
#define ull unsigned long long
#define inf 0x3f3f3f3f
#define idx(x) (x-'A')
using namespace std; int n,cte;
int head[NN];
char str[NN];
struct Edge{int to,nxt;}edge[NN*];
void ae(int u,int v){
cte++;edge[cte].nxt=head[u];
edge[cte].to=v,head[u]=cte;
}
struct node{
int x,s;
node(int x,int s):x(x),s(s){}
node(){}
}fa[NN][MM];
int dis[NN][MM];
namespace AC{
int ch[NN][],fail[NN],ed[NN],val[NN],tot;
void Build_Trie(char *str,int len,int id)
{
int x=;
for(int i=;i<=len;i++){
if(!ch[x][idx(str[i])])
ch[x][idx(str[i])]=++tot,val[tot]=idx(str[i]);
x=ch[x][idx(str[i])];
}ed[x]|=(<<(id-));
}
void Build_Fail()
{
queue<int>q;
for(int i=;i<;i++)
if(ch[][i]) q.push(ch[][i]);
while(!q.empty())
{
int x=q.front();q.pop();
ae(fail[x],x);
for(int i=;i<;i++)
{
if(ch[x][i]){
fail[ch[x][i]]=ch[fail[x]][i];
q.push(ch[x][i]);
}else{
ch[x][i]=ch[fail[x]][i];
}
}
}
q.push();
while(!q.empty())
{
int x=q.front();q.pop();
for(int j=head[x];j;j=edge[j].nxt){
int v=edge[j].to;
ed[v]|=ed[x];
q.push(v);
}
}
}
node Bfs()
{
queue<node>q;
memset(dis,0x3f,sizeof(dis));
q.push(node(,));
dis[][]=;
node k1,k2;
int x,v,s,t;
while(!q.empty())
{
k1=q.front();q.pop();
x=k1.x,s=k1.s;
if(s==(<<n)-) return k1;
for(int i=;i<;i++)
{
v=ch[x][i],t=s|ed[v];
if(dis[v][t]>dis[x][s]+){
dis[v][t]=dis[x][s]+;
fa[v][t]=k1;
q.push(node(v,t));
}
}
}
/*for(int i=1;i<=tot;i++)
printf("%d:%d\n",i,dis[i][(1<<n)-1]);*/
}
char Ans[NN];
void solve()
{
for(int i=;i<=n;i++){
scanf("%s",str+);
int len=strlen(str+);
Build_Trie(str,len,i);}
Build_Fail();
node ans=Bfs();
node a=ans;
int num=;
while(a.x||a.s){
Ans[++num]=val[a.x]+'A';
a=fa[a.x][a.s];}
for(int i=num;i>;i--)
printf("%c",Ans[i]);
puts("");
}
}; int main()
{
//freopen("t2.in","r",stdin);
scanf("%d",&n);
AC::solve();
return ;
}
BZOJ 1195 [HNOI2006]最短母串 (Trie图+状压+bfs最短路)的更多相关文章
- BZOJ 1195: [HNOI2006]最短母串 AC自动机+状压+搜索
思路比较直接. 由于 $n$ 很小,直接定义 $f[i][j]$ 表示当前在自动机中的节点 $i,$ 被覆盖串的集合为 $j$ 的方案数. #include <bits/stdc++.h> ...
- bzoj1195 [HNOI2006]最短母串 AC 自动机+状压+bfs
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1195 题解 建立 AC 自动机,然后构建出 trie 图. 然后直接在 trie 图上走.但是 ...
- bzoj 1195: [HNOI2006]最短母串 爆搜
1195: [HNOI2006]最短母串 Time Limit: 10 Sec Memory Limit: 32 MBSubmit: 894 Solved: 288[Submit][Status] ...
- BZOJ 1195: [HNOI2006]最短母串
1195: [HNOI2006]最短母串 Time Limit: 10 Sec Memory Limit: 32 MBSubmit: 1346 Solved: 450[Submit][Status ...
- bzoj 1195 [HNOI2006]最短母串 bfs 状压 最短路 AC自动机
LINK:最短母串 求母串的问题.不适合SAM. 可以先简化问题 考虑给出的n个字符串不存在包含关系. 那么 那么存在的情况 只可能有 两个字符串拼接起来能表示另外一个字符串 或者某个字符串的后缀可以 ...
- 【bzoj1195】[HNOI2006]最短母串 AC自动机+状态压缩+BFS最短路
原文地址:http://www.cnblogs.com/GXZlegend/p/6825226.html 题目描述 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串 ...
- 【刷题】BZOJ 1195 [HNOI2006]最短母串
Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. Input 第一行是一个正整数n(n<=12) ...
- [HNOI2006]最短母串 (AC自动机+状压)
Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. Input 第一行是一个正整数n(n<=12) ...
- bzoj 1195: [HNOI2006]最短母串【状压dp】
我有病吧--明明直接枚举是否匹配就可以非要写hash,然后果然冲突了(--我个非酋居然还敢用hash 设f[s][i]为已选串状态为s并且最后一个串是i,还有预处理出g[i][j]表示最长有长为g[i ...
随机推荐
- ZBrush中Document特性介绍
ZBrush®中的Document调色板用于加载或保存ZBrush文档,导入背景图像.导出背景图像.调整画布大小和设置背景颜色.本文小编来给大家介绍下Document常用的一些基本功能. ZBrush ...
- 页面元素的定位:getBoundingClientRect()和document.documentElement.scrollTop
1.document.documentElement.getBoundingClientRect MSDN对此的解释是: Syntax oRect = object.getBoundingClient ...
- Kendo UI diagram 更改connnect线颜色,及shapes的属性值
1.改diagram中连线的颜色:redraw一下就OK // Change the Line Green diagram.connections[indexS].redraw({ stroke:{ ...
- Eclipse Maven 创建Hello World Web项目
通过Eclipse创建Maven Web项目的简单步骤 先决条件 (Prerequisites) 1,JDK environment, 具体的安装JDK的步骤和环境配置一般网上都有,这里就不在赘述. ...
- JS侧边栏实现
<!DOCTYPE html> <html lang="en"> <style> </style> <head> < ...
- Mybatis 中 foreach collection 的三种用法
foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合. foreach元素的属性主要有 item,index,collection,open,separator,close. ...
- 3.is null和is not null
3.WHERE中使用is null和is not null //查询工资是null空值的人 select * from person where salary is null; //查询工 ...
- Ubuntu 15.10 安装Qt5.5.1
本系列文章由 @YhL_Leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/50300447 本人使用的ubuntu系 ...
- WinServer-win7通过powershell操作AD-从接触到放弃
额....我想在win7上练习AD的powershell命令 看了这篇帖子,他们说在WIN7上没法导入powershell的模块,只能在SERVER 上弄 https://social.technet ...
- Test Precisely and Concretely
Test Precisely and Concretely Kevlin Henney IT IS IMPORTANT TO TEST for the desired, essential behav ...