HDU 3247 Resource Archiver (AC自己主动机 + BFS + 状态压缩DP)
题目链接:Resource Archiver
解析:n个正常的串。m个病毒串,问包括全部正常串(可重叠)且不包括不论什么病毒串的字符串的最小长度为多少。
AC自己主动机 + bfs + 状态压缩DP
用最短路预处理出状态的转移。能够优化非常多
AC代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std; const int INF = 0x3f3f3f3f;
struct Trie{
int next[60010][2], fail[60010], end[60010];
int root, L;
int newnode(){
for(int i=0; i<2; i++) next[L][i] = -1;
end[L++] = 0;
return L-1;
}
void init(){
L = 0;
root = newnode();
}
void insert(char buf[], int id){
int len = strlen(buf);
int now = root;
for(int i=0; i<len; i++){
if(next[now][buf[i] - '0'] == -1)
next[now][buf[i] - '0'] = newnode();
now = next[now][buf[i] - '0'];
}
end[now] = id;
}
void build(){
queue<int> Q;
fail[root] = root;
for(int i=0; i<2; i++)
if(next[root][i] == -1) next[root][i] = root;
else{
fail[ next[root][i] ] = root;
Q.push(next[root][i]);
}
while(!Q.empty()){
int now = Q.front();
Q.pop();
if(end[ fail[now] ] == -1) end[now] = -1;
else end[now] |= end[ fail[now] ];
for(int i=0; i<2; i++)
if(next[now][i] == -1) next[now][i] = next[ fail[now] ][i];
else{
fail[ next[now][i] ] = next[ fail[now] ][i];
Q.push(next[now][i]);
}
}
}
int g[11][11];
int dp[1025][11];
int cnt;
int pos[11];
int dis[60010]; void bfs(int k){
queue<int> q;
memset(dis, -1, sizeof(dis));
dis[pos[k]] = 0;
q.push(pos[k]);
while(!q.empty()){
int now = q.front();
q.pop();
for(int i=0; i<2; i++){
int tmp = next[now][i];
if(dis[tmp] < 0 && end[tmp] >= 0){
dis[tmp] = dis[now] + 1;
q.push(tmp);
}
}
}
for(int i=0; i<cnt; i++) g[k][i] = dis[pos[i]];
} int solve(int n){
pos[0] = 0;
cnt = 1;
for(int i=0; i<L; i++)
if(end[i] > 0) pos[cnt++] = i;
for(int i=0; i<cnt; i++) bfs(i); for(int i=0; i<(1<<n); i++)
for(int j=0; j<cnt; j++)
dp[i][j] = INF;
dp[0][0] = 0;
for(int i=0; i<(1<<n); i++)
for(int j=0; j<cnt; j++)
if(dp[i][j] < INF){
for(int k=0; k<cnt; k++){
if(g[j][k] < 0) continue;
if(j == k) continue;
dp[i | end[pos[k]]][k] = min(dp[i | end[pos[k]]][k], dp[i][j] + g[j][k]);
}
}
int ans = INF;
for(int i=0; i<cnt; i++)
ans = min(ans, dp[(1<<n)-1][i]);
return ans;
}
}; char buf[1010];
Trie ac; int main(){
#ifdef sxk
freopen("in.txt", "r", stdin);
#endif // sxk
int n, m;
while(scanf("%d%d", &n, &m) == 2){
if(n == 0 && m == 0) break;
ac.init();
for(int i=0; i<n; i++){
scanf("%s", buf);
ac.insert(buf, 1<<i);
}
for(int i=0; i<m; i++){
scanf("%s", buf);
ac.insert(buf, -1);
}
ac.build();
printf("%d\n", ac.solve(n));
}
return 0;
}
HDU 3247 Resource Archiver (AC自己主动机 + BFS + 状态压缩DP)的更多相关文章
- HDU 3247 Resource Archiver (AC自动机+BFS+状压DP)
题意:给定 n 个文本串,m个病毒串,文本串重叠部分可以合并,但合并后不能含有病毒串,问所有文本串合并后最短多长. 析:先把所有的文本串和病毒都插入到AC自动机上,不过标记不一样,可以给病毒标记-1, ...
- HDU - 3247 Resource Archiver (AC自动机,状压dp)
\(\quad\)Great! Your new software is almost finished! The only thing left to do is archiving all you ...
- POJ 3691 & HDU 2457 DNA repair (AC自己主动机,DP)
http://poj.org/problem?id=3691 http://acm.hdu.edu.cn/showproblem.php?pid=2457 DNA repair Time Limit: ...
- HDU 2825 Wireless Password (AC自己主动机,DP)
pid=2825">http://acm.hdu.edu.cn/showproblem.php? pid=2825 Wireless Password Time Limit: 2000 ...
- HDU 2896 病毒侵袭 (AC自己主动机)
pid=2896">http://acm.hdu.edu.cn/showproblem.php?pid=2896 病毒侵袭 Time Limit: 2000/1000 MS (Java ...
- hdu 2222 Keywords Search ac自己主动机
点击打开链接题目链接 Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Ja ...
- HDU 2896 病毒侵袭 AC自己主动机题解
本题是在text里面查找key word的增强版.由于这里有多个text. 那么就不能够简单把Trie的叶子标志记录改动成-1进行加速了,能够使用其它技术.我直接使用个vis数组记录已经訪问过的节点, ...
- HDU - 2825 Wireless Password(AC自己主动机+DP)
Description Liyuan lives in a old apartment. One day, he suddenly found that there was a wireless ne ...
- HDU 2222 Keywords Search AC自己主动机入门题
单词统计的题目,给出一些单词,统计有多少单词在一个文本中出现,最经典的入门题了. AC自己主动机的基础: 1 Trie. 以这个数据结构为基础的,只是添加一个fail指针和构造fail的函数 2 KM ...
随机推荐
- 洛谷1002 容斥原理+dfs OR DP
//By SiriusRen #include <bits/stdc++.h> using namespace std; #define int long long ,,,,-,-,-,- ...
- Centos7基本命令
shell基本命令 linux命令行的组成结构 linux系统命令操作语法格式 命令 空格 参数 空格 文件路径或者需要处理的内容 rm -rf /tmp/* ls -la /home ...
- jQuery自适应倒计时插件
jQuery自适应倒计时插件 在线演示本地下载
- LinearLayout中间布局填充出现的问题
线性布局如何中间填充,会挤掉他下面的布局,所以中间填充使用layout_weight属性.
- 2016.01.08 Javascript视频
完成JavaScript开发视频课程的Ajax部分内容.
- view.getParent()与view.getRootView()
顾名思义,getParent就是获取view的父亲节点,而getRootView是寻找当前的view层次中处在最顶层的view,可理解为找出该view实例所在的view层次的根view. 如果这个vi ...
- 网络爬虫 robots协议 robots.txt
网络爬虫 网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网上下载网页,是搜索引擎的重要组成.传统爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上 ...
- linux虚拟主机的三种方法
虚拟主机虚拟主机是将一台(或者一组)服务器的资源(系统资源.网络带宽.存储空间等)按照一定的比例分割成若干相对独立的“小主机”的技术.每一台这样的“小主机”在功能上都可以实现WWW.FTP.Mail等 ...
- codevs——4189 字典&&HihoCoder #1014 : Trie树
题目描述 Description 最经,skyzhong得到了一本好厉害的字典,这个字典里整整有n个单词(1<=n<=200000) 现在skyzhong需要在字典里查询以某一段字母开头的 ...
- Going Home HDU - 1533(最大费用最小流)
On a grid map there are n little men and n houses. In each unit time, every little man can move one ...