uva 1399 - Puzzle(AC自动机)
来源:互联网 发布:日本经济数据2016 编辑:程序博客网 时间:2024/05/23 01:21
题目链接:uva 1399 - Puzzle
题目大意:给定K和N,表示有K种不同的字符,N个禁止串,求一个最长的串使得该串不包含任何禁止串为子串。如果存在循环或者不能构成的话,输出No。
解题思路:建立AC自动机,然后在AC自动机上做dp,所有单词结尾节点为禁止点。
#include <cstdio>#include <cstring>#include <queue>#include <algorithm>using namespace std;const int maxn = 50005;const int sigma_size = 26;struct Aho_Corasick { int sz, ac[maxn][sigma_size]; int fail[maxn], last[maxn]; void init(); int idx(char ch); void insert(char* s); void get_fail();}fuck;int K, vis[maxn], dp[maxn], jump[maxn];int dfs (int u) { if (vis[u]) return -1; if (dp[u] != -1) return dp[u]; vis[u] = 1; int& ret = dp[u]; jump[u] = -1; ret = 0; for (int i = K - 1; i >= 0; i--) { int v = fuck.ac[u][i]; if (fuck.last[v] == 0) { int tmp = dfs(v); if (tmp == -1) return -1; if (tmp + 1 > ret) { ret = tmp + 1; jump[u] = i; } } } vis[u] = 0; return ret;}void put_ans (int u) { while (jump[u] != -1) { printf("%c", 'A' + jump[u]); u = fuck.ac[u][jump[u]]; } printf("\n");}int main () { int cas, n; char word[55]; scanf("%d", &cas); while (cas--) { fuck.init(); memset(vis, 0, sizeof(vis)); memset(dp, -1, sizeof(dp)); scanf("%d%d", &K, &n); for (int i = 0; i < n; i++) { scanf("%s", word); fuck.insert(word); } fuck.get_fail(); if (dfs(0) != -1 && dp[0]) put_ans(0); else printf("No\n"); } return 0;}void Aho_Corasick::init() { sz = 1; memset(ac[0], 0, sizeof(ac[0]));}int Aho_Corasick::idx(char ch) { return ch - 'A';}void Aho_Corasick::insert(char* s) { int n = strlen(s), u = 0; for (int i = 0; i < n; i++) { int v = idx(s[i]); if (ac[u][v] == 0) { memset(ac[sz], 0, sizeof(ac[sz])); last[sz] = 0; ac[u][v] = sz++; } u = ac[u][v]; } last[u] = 1;}void Aho_Corasick::get_fail () { queue<int> que; fail[0] = 0; for (int i = 0; i < sigma_size; i++) { int u = ac[0][i]; if (u) { fail[u] = 0; que.push(u); } } while (!que.empty()) { int r = que.front(); que.pop(); for (int i = 0; i < K; i++) { int u = ac[r][i]; if (u == 0) { ac[r][i] = ac[fail[r]][i]; continue; } que.push(u); int v = fail[r]; while (v && ac[v][i] == 0) v = fail[v]; fail[u] = ac[v][i]; last[u] |= last[fail[u]]; } }}
1 0
- uva 1399 - Puzzle(AC自动机)
- UVA 1399 - Puzzle(AC自动机+DP)
- Uva-227 - Puzzle-AC
- UVa 227 Puzzle AC
- uva 11019 AC自动机
- uva 1449 AC自动机
- UVA 11019 AC自动机
- uva1399 - Puzzle AC自动机+记忆化搜索
- LA 3907 Puzzle(AC自动机)
- 求一个最长的串使得该串不包含任何禁止串为子串 AC自动机+DP +dfs判环 UVA 1399 - Puzzle
- UVA 1399 Puzzle 求一个最长的串使得该串不包含任何禁止串为子串 AC自动机 + DP +dfs判环
- UVA LA 4670(AC自动机)
- UVA 11468 Substring AC自动机
- AC自动机 (uva 1449)
- UVA 11468 - Substring(AC自动机)
- UVA 11468 Ac自动机+dp
- uva 11468 ac自动机+dp
- Uva 11468 Substring (AC自动机)
- 小黑小波比.nodejs技巧
- 运筹学在七十年代的失败
- ORACLE 数据库导入、导出(备份、恢复)
- Linux 中页的回收
- 10个强大的Apache开源模块
- uva 1399 - Puzzle(AC自动机)
- TCP/IP详解--三次握手和四次握手 Dos攻击
- java中static作用详解
- 1085 - All Possible Increasing Subsequences[树状数组]
- 第十一章 11.3.4节练习
- 基础图形管线
- ThreadLocal保证DateFormat线程安全
- Java现场信息获取蛋疼方法
- 天猫大数据总结2