Resource Archiver hdu3247
来源:互联网 发布:java八种基本数据类型 编辑:程序博客网 时间:2024/05/17 22:01
通过这题加深了对trie图的认识,trie图建好之后,匹配就不再需要fail指针了,在解决生成串类问题中,由于有禁止的包含的串,一定不能用fail指针进行转移,否则生成的串中有可能包含禁止串。
这道题关键在bfs求0点和resource串尾节点这些点俩俩之间最小距离,有俩种方法,
第一种是只通过ch来转移,但这样求出来的最短路不一定是最短的,因为有些resource串可能是另一些resource串的后缀,这相当于他们之间的最短路径是0,而这种情况是没有被考虑进来的,所以这就要求我们在DP转移时做文章,详细见代码。
第二种是通过ch和fail共同转移,但是通过fail指针进行转移时代价为0,而且只修改fail指针指向节点的距离值,但不把节点加入到队列中,这样处理完之后,就相当于一个普通的图了, 剩下的就是一个裸的TSP问题了。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <queue>#include <algorithm>#include <vector>#include <cstring>#include <stack>#include <cctype>#include <utility> #include <map>#include <string> #include <climits> #include <set>#include <string> #include <sstream>#include <utility> #include <ctime>using std::priority_queue;using std::vector;using std::swap;using std::stack;using std::sort;using std::max;using std::min;using std::pair;using std::map;using std::string;using std::cin;using std::cout;using std::set;using std::queue;using std::string;using std::istringstream;using std::make_pair;using std::getline;using std::greater;using std::endl;using std::multimap;typedef long long LL;typedef unsigned long long ULL;typedef pair<int, int> PAIR;typedef multimap<int, int> MMAP;const int MAXN(60010);const int SIGMA_SIZE(2);const int MAXM(110);const int MAXE(4000010);const int MAXH(18);const int INFI((INT_MAX-1) >> 2);const int MOD(10007);const ULL LIM(1000000000000000ull);int point[12];int que[MAXN];int front, back;struct AC{ int ch[MAXN][SIGMA_SIZE]; int f[MAXN], state[MAXN]; bool val[MAXN]; int size; void init() { memset(ch[0], 0, sizeof(ch[0])); f[0] = state[0] = 0; val[0] = false; size = 1; } inline int idx(char temp) { return temp-'0'; } void insert(char *S, bool flag, int num = -1) { int u = 0, id; for(; *S; ++S) { id = idx(*S); if(!ch[u][id]) { memset(ch[size], 0, sizeof(ch[size])); val[size] = false; state[size] = 0; ch[u][id] = size++; } u = ch[u][id]; } if(!flag){ point[num] = u;state[u] |= (1 << num); //标记resource串} val[u] |= flag; //标记virus串 } void construct() { front = back = 0; int cur, u; for(int i = 0; i < SIGMA_SIZE; ++i) { u = ch[0][i]; if(u) { que[back++] = u; f[u] = 0; } } while(front < back) { cur = que[front++]; for(int i = 0; i < SIGMA_SIZE; ++i) { u = ch[cur][i]; if(u) { que[back++] = u; f[u] = ch[f[cur]][i];state[u] |= state[f[u]]; val[u] |= val[f[u]]; } else ch[cur][i] = ch[f[cur]][i]; } } }};AC ac;void bfs(int s, int *dist) //求0点和所有resource串结尾节点之间最短路径{ for(int i = 0; i < ac.size; ++i) dist[i] = INFI; dist[point[s]] = 0;front = back = 0;que[back++] = point[s];int cur, tv; while(front < back) { cur = que[front++]; tv = ac.ch[cur][0]; //注意此处只能通过ch进行转移 //如果通过fail指针转移则只能修改点权,但不能将其入队,如果将其入队,可能会导致 //访问路径中出现非法串 if(!ac.val[tv] && dist[tv] == INFI) { dist[tv] = dist[cur]+1; que[back++] = tv; } tv = ac.ch[cur][1]; if(!ac.val[tv] && dist[tv] == INFI) { dist[tv] = dist[cur]+1; que[back++] = tv; } }}int dist[12][MAXN];char str[1010];int table[12][1 << 11]; void solve(int n){ int lim = (1 << (n+1))-1; for(int i = 0; i <= n; ++i) for(int j = 0; j <= lim; ++j) table[i][j] = INFI; table[0][1] = 0; for(int i = 1; i < lim; ++i) { for(int j = 0; j <= n; ++j)if((i&(1 << j)) && table[j][i] != INFI)for(int k = 0; k <= n; ++k){int ts = i|ac.state[point[k]]; //到达一个节点后,可能有多个串被同时访问table[k][ts] = min(table[k][ts], table[j][i]+dist[j][point[k]]);} } int ans = INFI; for(int i = 0; i <= n; ++i) ans = min(ans, table[i][lim]); printf("%d\n", ans);}int main(){ int n, m; while(scanf("%d%d", &n, &m), n+m) { ac.init(); point[0] = 0; for(int i = 1; i <= n; ++i) { scanf("%s", str); //resource ac.insert(str, false, i); } for(int i = 0; i < m; ++i) { scanf("%s", str); //virus ac.insert(str, true); } ac.construct(); for(int i = 0; i <= n; ++i) bfs(i, dist[i]); solve(n); } return 0;}
- Resource Archiver hdu3247
- HDU3247 Resource Archiver
- HDU3247 Resource Archiver(AC自动机+DP)
- hdu3247 Resource Archiver AC自动机+状态压缩DP
- hdu 3247 Resource Archiver
- hdu 3247 Resource Archiver
- HDU 3247 Resource Archiver
- HDU 3247Resource Archiver
- 【AC自动机】 HDOJ 3247 Resource Archiver
- hdu3341 Resource Archiver AC自动机+DP
- zoj 3190 Resource Archiver 【构造最短不含病毒串的串】
- HDU 3247 Resource Archiver(AC自动机+BFS+状态DP)
- hdu 3247 Resource Archiver(AC自动机+状压DP)
- 【ZOJ】 3190 Resource Archiver AC自动机+BFS预处理+DP
- [AC自动机+spfa+状压dp] hdu 3247 Resource Archiver
- hdu 3247 Resource Archiver(AC自动机+BFS+DP)
- hdu 3247 Resource Archiver (ac自动机+BFS+状压dp)
- HDU 3247 Resource Archiver[AC自动机+最短路+dp]
- SubmitStatusWeb Board(完全背包)
- 《C和指针》的第一个例子
- English notes for Time
- 数码管SR420561K SR410561K的引脚图
- ubuntu下git服务器的简单配置
- Resource Archiver hdu3247
- Nginx入门之二
- Zen coding的css用法
- OpenCV学习笔记(二)——新版本模块结构
- 进程间通信之共享内存
- 六种异常处理的陋习
- FFT算法的物理意义
- Cylinder(圆柱体)(枚举)
- Java反射机制