Description

Great! Your new software is almost finished! The only thing left to do is archiving all your n resource files into a big one. 
Wait a minute… you realized that it isn’t as easy as you thought. Think about the virus killers. They’ll find your software suspicious, if your software contains one of the m predefined virus codes. You absolutely don’t want this to happen. 
Technically, resource files and virus codes are merely 01 strings. You’ve already convinced yourself that none of the resource strings contain a virus code, but if you make the archive arbitrarily, virus codes can still be found somewhere. 
Here comes your task (formally): design a 01 string that contains all your resources (their occurrences can overlap), but none of the virus codes. To make your software smaller in size, the string should be as short as possible.

Input

There will be at most 10 test cases, each begins with two integers in a single line: n and m (2 <= n <= 10, 1 <= m <= 1000). The next n lines contain the resources, one in each line. The next m lines contain the virus codes, one in each line. The resources and virus codes are all non-empty 01 strings without spaces inside. Each resource is at most 1000 characters long. The total length of all virus codes is at most 50000. The input ends with n = m = 0.

Output

For each test case, print the length of shortest string.

Sample Input

2 2
1110
0111
101
1001
0 0

Sample Output

5

题目大意:给n个资源01串和m个病毒01串。构造一个最短的01串使其包含所有的资源串,但不包含任何一个病毒串。
题目分析:建立好AC自动机后,在上面广搜即可。 代码如下:
# include<iostream>
# include<cstdio>
# include<queue>
# include<cstring>
# include<algorithm>
using namespace std; const int N=10000; int ch[6*N+5][2];
int fail[6*N+5];
int sz,type[6*N+5]; void init()
{
sz=0;
memset(ch,-1,sizeof(ch));
memset(type,0,sizeof(type));
} int idx(char c)
{
return c-'0';
} void insert(char *s,int val)
{
int r=0;
int n=strlen(s);
for(int i=0;i<n;++i){
int c=idx(s[i]);
if(ch[r][c]==-1) ch[r][c]=++sz;
r=ch[r][c];
}
type[r]=val;
} void getFail()
{
queue<int>q;
fail[0]=0;
for(int i=0;i<2;++i){
if(ch[0][i]==-1)
ch[0][i]=0;
else{
q.push(ch[0][i]);
fail[ch[0][i]]=0;
}
}
while(!q.empty())
{
int u=q.front();
q.pop();
if(type[fail[u]]>0)
type[u]|=type[fail[u]];
for(int i=0;i<2;++i){
if(ch[u][i]==-1)
ch[u][i]=ch[fail[u]][i];
else{
fail[ch[u][i]]=ch[fail[u]][i];
q.push(ch[u][i]);
}
}
}
} struct Node
{
int step;
int loca;
int sta;
};
int n,m;
char s[1005];
char vis[6*N+5][1<<10]; int bfs()
{
queue<Node>q;
memset(vis,0,sizeof(vis));
q.push(Node{0,0,0});
while(!q.empty())
{
Node u=q.front();
q.pop();
if(u.sta==(1<<n)-1)
return u.step;
for(int i=0;i<2;++i) if(type[ch[u.loca][i]]>=0){
int v=ch[u.loca][i];
if(vis[v][u.sta|type[v]]) continue;
vis[v][u.sta|type[v]]=1;
q.push(Node{u.step+1,v,u.sta|type[v]});
}
}
return -1;
} int main()
{
while(~scanf("%d%d",&n,&m)&&(n+m))
{
init();
for(int i=0;i<n;++i){
scanf("%s",s);
insert(s,1<<i);
}
for(int i=0;i<m;++i){
scanf("%s",s);
insert(s,-1);
}
getFail();
printf("%d\n",bfs());
}
return 0;
}

  


HDU-3247 Resource Archiver(AC自动机+BFS)的更多相关文章

  1. HDU 3247 Resource Archiver (AC自动机+BFS+状压DP)

    题意:给定 n 个文本串,m个病毒串,文本串重叠部分可以合并,但合并后不能含有病毒串,问所有文本串合并后最短多长. 析:先把所有的文本串和病毒都插入到AC自动机上,不过标记不一样,可以给病毒标记-1, ...

  2. HDU - 3247 Resource Archiver (AC自动机,状压dp)

    \(\quad\)Great! Your new software is almost finished! The only thing left to do is archiving all you ...

  3. HDU3247 Resource Archiver —— AC自动机 + BFS最短路 + 状压DP

    题目链接:https://vjudge.net/problem/HDU-3247 Resource Archiver Time Limit: 20000/10000 MS (Java/Others)  ...

  4. HDU 3247 Resource Archiver(AC自动机 + 状压DP + bfs预处理)题解

    题意:目标串n( <= 10)个,病毒串m( < 1000)个,问包含所有目标串无病毒串的最小长度 思路:貌似是个简单的状压DP + AC自动机,但是发现dp[1 << n][ ...

  5. HDU 3247 Resource Archiver (AC自己主动机 + BFS + 状态压缩DP)

    题目链接:Resource Archiver 解析:n个正常的串.m个病毒串,问包括全部正常串(可重叠)且不包括不论什么病毒串的字符串的最小长度为多少. AC自己主动机 + bfs + 状态压缩DP ...

  6. hdu_3247_Resource Archiver(AC自动机+bfs+TSP)

    题目链接:hdu_3247_Resource Archiver 题意: 有n个资源串,m个病毒串,现在要将所有的资源串整合到一个串内,并且这个串不能包括病毒串,问最短的串长为多少 题解: 将资源串和病 ...

  7. HDU3247 Resource Archiver (AC自动机+spfa+状压DP)

    Great! Your new software is almost finished! The only thing left to do is archiving all your n resou ...

  8. hdu 2896 病毒侵袭 ac自动机

    /* hdu 2896 病毒侵袭 ac自动机 从题意得知,模式串中没有重复的串出现,所以结构体中可以将last[](后缀链接)数组去掉 last[]数组主要是记录具有相同后缀模式串的末尾节点编号 .本 ...

  9. hdu 2896 病毒侵袭 AC自动机(查找包含哪些子串)

    病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  10. Resource Archiver HDU - 3247 AC自动机+BFS+状压

    题意: 给出n个资源串,m个病毒串,现在要如何连接资源串使得不含病毒串(可以重叠,样例就是重叠的). 题解: 这题的套路和之前的很不同了,之前的AC自动机+DP的题目一般都是通过teir图去转移, 这 ...

随机推荐

  1. 解决 主界面mainactivity 中fragment弹框把下面tab选项卡 顶上去的方案

     android:windowSoftInputMode="adjustPan"            android:configChanges="screenSize ...

  2. Ubuntu的多文件编译以及c语言的数组、函数

    闲言少叙,直接切入主题. 一.Linux下的多文件编译(Ubuntu系统). 对于小程序来说,往往一个.c文件就足够了,里面包含了各种主函数和功能函数,以及函数的声明等等.但是这样的弊端主要有两点,一 ...

  3. DotSpatial 创建面状要素——含空洞

    private void toolStripButton23_Click(object sender, EventArgs e) { //选择图层 FeatureSet fs = null; fs = ...

  4. 华为手机调试显示log日志

    华为手机默认状态手机log为关闭状态,所以看不到详细错误信息. 手机拨号*#*#2846579#*#*,进入projectmenu--后台设置--LOG设置--LOG开关--打开 勾选AP日志   C ...

  5. window上利用pip安装pandas

    官网推荐的是直接使用Anoconda,它集成了pandas,可以直接使用.安装挺简单的,有windows下的安装包.如果不想安装庞大的Anoconda,那就一步一步用pip来安装pandas.下面我主 ...

  6. windows上传代码到github

    上传代码到github上有很多种方法,在这里我介绍一种比较简单的一种.工具嘛,越简单越好用啊. 1.首先下载github在windows下的客户端 下载地址:https://desktop.githu ...

  7. laravel in centos

    如果遇到: phpunit.... To enable extensions, verify that they are enabled in those .ini files: - /etc/php ...

  8. join()方法之我见

    JavaScript join() 方法 定义和用法 join() 方法用于把数组中的所有元素放入一个字符串. 元素是通过指定的分隔符进行分隔的. 语法 arrayObject.join(separa ...

  9. jsp提交表单数据乱码,内置对象,以及过滤器

    jsp提交表单数据乱码解决方案 通过form表单给服务器提交数据的时候,如果提交的是中文数据,那么可能会出现乱码,如果表单的请求方式是post请求,那么可以使用如下方案解决乱码: 在调用getPara ...

  10. hadoop2的高可用性

    1   hadoop2  namenode由一个节点变成两个节点,同时在线,且同时只有一个是活跃的,如果一个出了问题,另外一个立即接替:没必要配置Secondary NameNode.Checkpoi ...