Kattis taboo (AC自动机 拓扑排序 DP)
2016-11-17 20:18
726 查看
题目链接:点击这里
题意:给出n个01串,要构造一个最长的串使得这个串不包含所有出现过的串,无解输出-1.首先把所有的点扔进自动机,因为出现过的串不能在我们构造的串中出现,所以事先把某些”坏点”标记,坏点指的就是每个串的结束节点以及沿着结束节点fail指针走下去的节点. 如果剩下的图中能够沿着根走出一个环那么必然就无解了, 判环可以用一遍拓扑确定. 排除无解情况剩下就是一个DAG了, 用dp[i][j]表示在自动机上i节点, 串长为j是否可行, 最后按照最长路打印方案即可.
#include <cstdio> #include <iostream> #include <cstring> #include <queue> #include <cmath> #include <algorithm> #include <stack> #define Clear(x,y) memset (x,y,sizeof(x)) #define fi first #define se second #define pii pair<int, int> #define pli pair<long long, int> #define pb push_back #define mod 1000000007 template <class T> inline bool scan (T &ret) { char c; int sgn; if (c = getchar(), c == EOF) return 0; //EOF while (c != '-' && (c < '0' || c > '9') ) c = getchar(); sgn = (c == '-') ? -1 : 1; ret = (c == '-') ? 0 : (c - '0'); while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0'); ret *= sgn; return 1; } using namespace std; #define maxn 500005 int G[maxn][2]; void add_edge (int u, int v, int w) { G[u][w] = v; } struct trie { int next[maxn][2], fail[maxn]; long long end[maxn]; int root, cnt; int new_node () { memset (next[cnt], -1, sizeof next[cnt]); end[cnt++] = 0; return cnt-1; } void init () { cnt = 0; root = new_node (); } void insert (char *buf) {//字典树插入一个单词 int len = strlen (buf); int now = root; for (int i = 0; i < len; i++) { int id = buf[i]-'0'; if (next[now][id] == -1) { next[now][id] = new_node (); } now = next[now][id]; if (end[now]) break; } end[now]++; } void build () {//构建fail指针 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 (); 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 in[maxn], in2[maxn]; bool vis[maxn], inq[maxn]; void dfs1 (int u) { for (int id = 0; id < 2; id++) { int j = next[u][id]; if (end[j]) continue; in[j]++; in2[j]++; if (in[j] == 1) dfs1 (j); } } bool topo () {///判环 Clear (inq, 0); Clear (vis, 0); Clear (in, 0); Clear (in2, 0); int tot = 0, num = 0; dfs1 (0); queue <int> q; while (!q.empty ()) q.pop (); if (in[0]) return 1; inq[0] = 1, vis[0] = 1; q.push (0); num++; while (!q.empty ()) { int u = q.front (); q.pop (); for (int id = 0; id < 2; id++) { int v = next[u][id]; if (end[v]) continue; in[v]--; vis[v] = 1; if (!in[v]) { q.push (v); inq[v] = 1; num++; } } } for (int i = 0; i < cnt; i++) { if (inq[i] != vis[i]) { return 1; } } return 0; } int dp[maxn], to[maxn], Max; int pre[maxn]; void dfs (int u) { for (int id = 0; id < 2; id++) { int v = next[u][id]; if (end[v]) continue; dfs (v); to[u] = max (to[u], to[v]+1); if (to[v]+dp[u]+1 == Max) { add_edge (u, v, id); } } } void query () { if (topo ()) { printf ("-1\n"); return ; } Clear (dp, 0); queue <int> q; while (!q.empty ()) q.pop (); q.push (0); Max = 0; while (!q.empty ()) { int u = q.front (); q.pop (); for (int id = 0; id < 2; id++) { int j = next[u][id]; if (end[j]) continue; if (dp[j] < dp[u]+1) { dp[j] = dp[u]+1; } in2[j]--; if (!in2[j]) { q.push (j); Max = max (Max, dp[j]); } } } Clear (G, -1); Clear (to, 0); dfs (0); int u = 0; while (dp[u] != Max) { if (G[u][0] != -1) { printf ("0"); u = G[u][0]; } else { printf ("1"); u = G[u][1]; } } printf ("\n"); } }ac; int n; char buf[maxn]; int main () { scanf ("%d", &n); ac.init (); for (int i = 0; i < n; i++) { scanf ("%s", buf); ac.insert (buf); } ac.build (); ac.query (); return 0; }
相关文章推荐
- 【BZOJ-1030】文本生成器 AC自动机 + DP
- POJ 3691 DNA repair 基于AC自动机的DP
- [数位DP 高精度 拓扑排序 bitset] BZOJ 2913 [Poi1997]XOR Gates
- AC自动机+有向拓扑判环 Taboo Kattis - taboo
- 【POJ2778】AC自动机,DP,矩阵乘法
- UVaLive 3490 - Generator (AC自动机 期望DP 高斯消元)
- 【BZOJ1638】[Usaco2007 Mar]Cow Traffic 奶牛交通【DAG】【拓扑排序】【DP】
- POJ 1625 Censored!(AC自动机,DP)
- UVALive 4126 Password Suspects(AC自动机 + DP)
- ZOJ 3494 BCD Code (数位DP,AC自动机)
- hdu4758 hdu2825 hdu4057 AC自动机与状态压缩dp的结合
- hdu 4117 GRE Words (ac自动机 线段树 dp)
- UVA - 11019 Matrix Matcher (AC自动机(二维匹配) + dp)
- CodeForces 86C Genetic engineering (AC自动机 上 DP)
- POJ 1625 Censored! (AC自动机 + 高精度 + DP)
- BZOJ 1030 [JSOI2007]文本生成器 (AC自动机 + DP)
- hdu4057 Rescue the Rabbit,AC自动机,状态压缩dp
- poj--1625Censored!+AC自动机上的dp+大数
- [数位DP AC自动机] Codeforces 434C Round #248 (Div. 1) C. Tachibana Kanade's Tofu
- 【dp,AC自动机】cf86C. Genetic engineering