HDU3247 Resource Archiver —— AC自动机 + BFS最短路 + 状压DP
题目链接:https://vjudge.net/problem/HDU-3247
Resource Archiver
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 100000/100000 K (Java/Others)
Total Submission(s): 3228 Accepted Submission(s): 1052
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.
1110
0111
101
1001
0 0
题意:
给出n个(n<=10)字符串,和m(m<=1000)个单词。求包含所有字符串,并且不包含任何一个单词的长串的最短长度。
题解:
1.看到n的大小为10,并且要求包含所有字符串,就很容易想到用状压DP。
1.1 设dp[status][u]为:当前状态为status(包含了哪些字符串),并且以字符串u结尾的最短长度。设cost[u][v]为:在字符串u后面接上字符串v所需要的最短长度。由于字符串之间可以有重叠,所以cost[u][v]可能小于len[v];由于长串不能包含单词,所以在链接u、v时,之间可能还需要加一些字符以便跳过单词,所以cost[u][v]可能大于len[v]。
1.2 假如求出了cost数组,那么剩下的就是典型TSP问题了。
2. 如何求cost数组呢?
2.1 把n个字符串和m个单词都插入到AC自动机中,并且需要对字符串和单词作相应的标记。
2.2 对于每个字符串,在自动机上跑最短路,求出当前字符串与其他字符串的最短距离,在跑的时候需要跳过单词。原理:AC自动机各个状态之间的关系构成了一张图。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const double EPS = 1e-;
const int INF = 2e9;
const LL LNF = 2e18;
const int MOD = 1e5;
const int MAXN = 5e4+1e4+; int n, m;
int Index[MAXN], pos[MAXN], cost[][], Len[MAXN];
int dp[<<][];
struct Trie
{
int sz, base;
int next[MAXN][], fail[MAXN], end[MAXN];
int root, L;
int newnode()
{
for(int i = ; i<sz; i++)
next[L][i] = -;
end[L++] = false;
return L-;
}
void init(int _sz, int _base)
{
sz = _sz;
base = _base;
L = ;
root = newnode();
}
int insert(char buf[], bool isVirus)
{
int len = strlen(buf);
int now = root;
for(int i = ; i<len; i++)
{
if(next[now][buf[i]-base] == -) next[now][buf[i]-base] = newnode();
now = next[now][buf[i]-base];
}
end[now] = isVirus;
return now;
}
void build()
{
queue<int>Q;
fail[root] = root;
for(int i = ; i<sz; i++)
{
if(next[root][i] == -) next[root][i] = root;
else fail[next[root][i]] = root, Q.push(next[root][i]);
}
while(!Q.empty())
{
int now = Q.front();
Q.pop();
end[now] |= end[fail[now]];
for(int i = ; i<sz; i++)
{
if(next[now][i] == -) next[now][i] = next[fail[now]][i];
else fail[next[now][i]] = next[fail[now]][i], Q.push(next[now][i]);
}
}
} int query()
{
for(int i = ; i<(<<n); i++)
for(int j = ; j<n; j++)
dp[i][j] = INF;
for(int j = ; j<n; j++)
dp[<<j][j] = Len[j]; for(int i = ; i<(<<n); i++)
for(int j = ; j<n; j++)
{
if(!(i&(<<j)) || dp[i][j]==INF) continue;
for(int k = ; k<n; k++)
if(!(i&(<<k)) && cost[j][k]!=INF)
dp[i|(<<k)][k] = min(dp[i|(<<k)][k], dp[i][j]+cost[j][k]);
} int ret = INF;
for(int i = ; i<n; i++)
ret = min(ret, dp[(<<n)-][i]);
return ret;
}
};
Trie ac; int dis[MAXN];
void BFS(int st)
{
queue<int> Q;
while(!Q.empty()) Q.pop();
for(int i = ; i<ac.L; i++)
dis[i] = INF;
dis[st] = ;
Q.push(st);
while(!Q.empty())
{
int u = Q.front(); Q.pop();
for(int i = ; i<ac.sz; i++)
{
int v = ac.next[u][i];
if(dis[v]==INF && !ac.end[v])
{
dis[v] = dis[u] + ;
Q.push(v);
}
}
}
for(int i = ; i<n; i++)
cost[Index[st]][i] = dis[pos[i]];
} char buf[MAXN];
int main()
{
while(scanf("%d%d",&n,&m)&&(n||m))
{
ac.init(,'');
memset(Index, -, sizeof(Index));
for(int i = ; i<n; i++)
{
scanf("%s", buf);
Len[i] = strlen(buf);
pos[i] = ac.insert(buf, false);
Index[pos[i]] = i;
}
for(int i = ; i<m; i++)
{
scanf("%s", buf);
ac.insert(buf, true);
}
ac.build();
for(int i = ; i<n; i++)
BFS(pos[i]); int ans = ac.query();
printf("%d\n", ans);
}
}
HDU3247 Resource Archiver —— AC自动机 + BFS最短路 + 状压DP的更多相关文章
- 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 ...
- HDU 3247 Resource Archiver (AC自动机+BFS+状压DP)
题意:给定 n 个文本串,m个病毒串,文本串重叠部分可以合并,但合并后不能含有病毒串,问所有文本串合并后最短多长. 析:先把所有的文本串和病毒都插入到AC自动机上,不过标记不一样,可以给病毒标记-1, ...
- hdu3247Resource Archiver (AC自动机+最短路+状压dp)
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 100000/100000 K (Java/Others) Total Submis ...
- HDU 4568 Hunter 最短路+状压DP
题意:给一个n*m的格子,格子中有一些数,如果是正整数则为到此格子的花费,如果为-1表示此格子不可到,现在给k个宝藏的地点(k<=13),求一个人从边界外一点进入整个棋盘,然后拿走所有能拿走的宝 ...
- 最短路+状压DP【洛谷P3489】 [POI2009]WIE-Hexer
P3489 [POI2009]WIE-Hexer 大陆上有n个村庄,m条双向道路,p种怪物,k个铁匠,每个铁匠会居住在一个村庄里,你到了那个村庄后可以让他给你打造剑,每个铁匠打造的剑都可以对付一些特定 ...
- 【BZOJ1097】[POI2007]旅游景点atr 最短路+状压DP
[BZOJ1097][POI2007]旅游景点atr Description FGD想从成都去上海旅游.在旅途中他希望经过一些城市并在那里欣赏风景,品尝风味小吃或者做其他的有趣的事情.经过这些城市的顺 ...
- hdu_3247_Resource Archiver(AC自动机+bfs+TSP)
题目链接:hdu_3247_Resource Archiver 题意: 有n个资源串,m个病毒串,现在要将所有的资源串整合到一个串内,并且这个串不能包括病毒串,问最短的串长为多少 题解: 将资源串和病 ...
- HDU - 3247 Resource Archiver (AC自动机,状压dp)
\(\quad\)Great! Your new software is almost finished! The only thing left to do is archiving all you ...
- 【CodeVS2800】 送外卖 最短路+状压DP
首先求出各点之间的最短路,floyed即可,注意是0-n. 然后考虑状压,f[i][j]表示状态为i时访问j点时的最短路和,1表示访问,0表示未访问,然后第j个点所在的位置就是(1<<j) ...
随机推荐
- lnmp环境网页访问慢排查思路
1.首先看每个服务器的负载情况 2.若各个服务器负载不高 首先查看是不是负载均衡服务器问题相接访问web服务看是否慢,若也慢则查看是不是访问动态页面慢,创建一个静态页面访问试试,若不慢则是动态页面问题 ...
- Docker 开源管理工具集锦
俗话说工欲善其事.必先利其器.Docker 是一种详细的虚拟化技术,Docker 尽管以RestAPI形式提供服务.但在实际生产环境中,管理大规模集群部署的Docker容器确实是一个巨大的挑战.尽管D ...
- linux 之体验(JDK7+Tomcat7+MySQL5.5)部署环境
---------------------------------------------------------------------------------------------------- ...
- linux 挂载移动盘
http://www.2cto.com/os/201411/354319.html 磁盘出现问题,有时候卸载不掉 参见http://blog.csdn.net/davil_dev/article/de ...
- hdu2141Can you find it?
给你四个集合.要你从这四个集合中 各取出一个数出来,推断,取出的前三个数的和 是否等于第四个数. 数据比較大.我的做法是将 前两个集合全部数全部和的情况取出来, 然后二分查找第四个集合和第三集合 ...
- 配置fio支持rbd測试引擎
fio的rbd測试引擎能够非常方便的对rbd进行測试.以下示范怎样安装fio支持rbd引擎. git clone git://git.kernel.dk/fio.git $ cd fio $ ./co ...
- 【WPF学习笔记】之如何设置下拉框读取SqlServer数据库的值:动画系列之(一)
先前条件:设置好数据库,需要三个文件CommandInfo.cs.DbHelperSQL.cs.myHelper.cs,需要修改命名空间,参照之前随笔http://www.cnblogs.com/Ow ...
- TOML简介 (转)
TOML的由来 配置文件的使用由来已久,从.ini.XML.JSON.YAML再到TOML,语言的表达能力越来越强,同时书写便捷性也在不断提升. TOML是前GitHub CEO, Tom Prest ...
- Mysql 索引增加与删除
[1]索引 索引,通俗理解,即目录. 之前说过,计算机是对现实世界的模拟.目录应用在数据库领域,即所谓的索引. 目录的作用显而易见,所以建立索引可以大大提高检索的速度. 但是,会降低更新表的速度,如对 ...
- UIWebView使用中的内存相关问题
本文转载至: http://blog.csdn.net/musou_ldns/article/details/7675589 applicationios5webkit测试cacheios 在iO ...