[BZOJ1195]:[HNOI2006]最短母串(AC自动机+BFS)
题目传送门
题目描述
给定n个字符串(S1,S2,…,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,…,Sn)都是T的子串。
输入格式
输出格式
样例
ABCD
BCDABC
数据范围与提示
题解
一看是多模式串,首先应该想到是AC自动机。
如果还不会AC自动机,可以转到这篇博客,个人感觉还是写的挺清楚的:AC自动机讲解+[HDU2222]:Keywords Search(AC自动机)。
那么我们考虑怎么去处理。
代码时刻
#include<bits/stdc++.h>
using namespace std;
int trie[5000][5000],cnt=1,ed[5000],nxt[5000];
char s[50];
int que[5000],que1[10000000],que2[10000000],que3[10000000],que4[10000000];
//que用于求Fail指针
//que1-4用于BFS,que1用于存储答案,que2用于存储上一个点在队列中的位置,que3用与存储当前点的编号,que4用于存储状态
bool vis[5000][5000];
int tot;
int n;
int ans[5000];
void insert(char *str,int id)//依然建树
{
int len=strlen(str);
int p=1;
for(int i=0;i<len;i++)
{
int ch=str[i]-'A';
if(!trie[p][ch])trie[p][ch]=++cnt;
p=trie[p][ch];
}
ed[p]|=1<<(id-1);
}
void build()//找Fail指针
{
for(int i=0;i<26;i++)trie[0][i]=1;
que[1]=1;
int head=1,tail=1;
while(head<=tail)
{
for(int i=0;i<26;i++)
{
if(!trie[que[head]][i])trie[que[head]][i]=trie[nxt[que[head]]][i];
else
{
que[++tail]=trie[que[head]][i];
nxt[trie[que[head]][i]]=trie[nxt[que[head]]][i];
ed[trie[que[head]][i]]|=ed[trie[nxt[que[head]]][i]];
}
}
head++;
}
}
void ask()//BFS
{
int head=1,tail=1;
int end=(1<<n)-1;
que3[1]=1;
while(head<=tail)
{
if(que4[head]==end)
{
while(head>1)
{
ans[++tot]=que1[head];
head=que2[head];
}
while(tot--)printf("%c",ans[tot+1]+'A');
return;
}
for(int i=0;i<26;i++)
if(!vis[trie[que3[head]][i]][que4[head]|ed[trie[que3[head]][i]]])//用vis存储当前状态有没有被访问过
{
que1[++tail]=i;//添加这个点
que2[tail]=head;//存储上一个点
que3[tail]=trie[que3[head]][i];//存储当前点的编号
que4[tail]=que4[head]|ed[trie[que3[head]][i]];//存储状态
vis[trie[que3[head]][i]][que4[head]|ed[trie[que3[head]][i]]]=1;//表示当前状态已经被访问过
}
head++;
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",s);
insert(s,i);
}
build();
ask();
return 0;
}
rp++
[BZOJ1195]:[HNOI2006]最短母串(AC自动机+BFS)的更多相关文章
- BZOJ1195[HNOI2006]最短母串——AC自动机+BFS+状态压缩
题目描述 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. 输入 第一行是一个正整数n(n<=12),表示给定的字符串的 ...
- BZOJ1195 [HNOI2006]最短母串 AC自动机 bfs
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 传送门 - BZOJ1195 题意概括 给出一堆串,然后求一个包含这些串的所有串的最短的中的字典序最小的. 题解 先造一个AC ...
- Bzoj1195 [HNOI2006]最短母串 [AC自动机]
Time Limit: 10 Sec Memory Limit: 32 MBSubmit: 1304 Solved: 439 Description 给定n个字符串(S1,S2,„,Sn),要求找 ...
- bzoj1195 [HNOI2006]最短母串 AC 自动机+状压+bfs
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1195 题解 建立 AC 自动机,然后构建出 trie 图. 然后直接在 trie 图上走.但是 ...
- BZOJ_1195_[HNOI2006]最短母串_AC自动机+BFS+分层图
BZOJ_1195_[HNOI2006]最短母串_AC自动机+BFS+分层图 Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2, ...
- 【bzoj1195】[HNOI2006]最短母串 AC自动机+状态压缩+BFS最短路
原文地址:http://www.cnblogs.com/GXZlegend/p/6825226.html 题目描述 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串 ...
- [HNOI2006]最短母串 (AC自动机+状压)
Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. Input 第一行是一个正整数n(n<=12) ...
- BZOJ 1195: [HNOI2006]最短母串 AC自动机+状压+搜索
思路比较直接. 由于 $n$ 很小,直接定义 $f[i][j]$ 表示当前在自动机中的节点 $i,$ 被覆盖串的集合为 $j$ 的方案数. #include <bits/stdc++.h> ...
- [bzoj1195][HNOI2006]最短母串_动态规划_状压dp
最短母串 bzoj-1195 HNOI-2006 题目大意:给一个包含n个字符串的字符集,求一个字典序最小的字符串使得字符集中所有的串都是该串的子串. 注释:$1\le n\le 12$,$1\le ...
- Bzoj1195 [HNOI2006]最短母串 [状态压缩]
Time Limit: 10 Sec Memory Limit: 32 MBSubmit: 1304 Solved: 439 Description 给定n个字符串(S1,S2,„,Sn),要求找 ...
随机推荐
- CodeForces-520E Pluses everywhere
题目描述 给出一个长度为 \(n\) 的字符串,给出一个非负整数 \(k\),要求给这个字符串中间添加 \(k\) 个$\(+\)'号,变成一个表 达式,比如"\(1000101\)&quo ...
- Comet OJ - Contest #14
Rank38. 还是比较不满意吧,C卡了太久,E没调出来,D也没空去做了. A 签到题. #include<bits/stdc++.h> using namespace std; #def ...
- js实现回车键搜索
前端关键代码: <input type="text" onkeydown="entersearch()" class="form-control ...
- PythonDay09
第九章函数 今日内容 函数定义 函数调用 函数返回值 函数的参数 函数定义 # 通过定义一个计算数据长度的函数,def为关键字,count_len是函数名def count_len(): lst = ...
- import和from.…import…
import和from.-import- 在讲之前我们先来讲一下怎样去下载第三方库,我们把python看作一部手机,pip就是应用管家,第三方库里面的模块就是应用管家里面的一个应用 一.import模 ...
- mysql文本后面带换行符导致查询不到
UPDATE tablename SET FIELD = REPLACE(REPLACE(FIELD, CHAR(10), ''), CHAR(13), ''); CHAR(10): 换行符 CH ...
- 剑指offer-最小的K个数-时间效率-排序-python
题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 这就是排序题(将结果的最小K值输出) # -*- coding ...
- 实现一个名为Person的类和它的子类Employee,Manager是Employee的子类,设计一个方法add用于涨工资,普通员工一次能涨10%,经理能涨20%。
1.实现一个名为Person的类和它的子类Employee,Manager是Employee的子类,设计一个方法add用于涨工资,普通员工一次能涨10%,经理能涨20%.具体要求如下:(1)Perso ...
- webpack3 打包
1. 基于 webpack 3.0 2.步骤.说明 2.1 webpack 本地初始化.安装基本包 npm init > package.json npm i webpack ...
- 使用MEMCACHED实现缓存
什么是memcached Memcached是一个自由开源的,高性能,分布式内存对象缓存系统. Memcached是以LiveJournal旗下Danga Interactive公司的Brad Fit ...