AC自动机+状压dp

多串匹配要想ac自动机

dp[i][S]表示在i状态选中S

转移就用bfs,每个点通过fail收集信息,不要忘记通过fail传递

昨天搞不明白为什么自动机每次只可以转移儿子,不可以转移fail,问了问大概知道因为儿子是最长的后缀,包含的信息最多,包含了其他fail的信息,就相当于收集了其他fail的东西,就不用走了,但是一定要收集,这跟kmp很像,kmp就是走最大的后缀,这里也是,这样就可以保证不遗补漏同时加速

字典序最大在bfs时已经保证了,感觉比较显然,每次先拓展字典序最小的字符,bfs又求最短路,正好保证了字典序最小

#include<bits/stdc++.h>
using namespace std;
const int N = ;
int n;
char s[N];
namespace ac_automation
{
int cnt, root, tot;
int id[N];
struct DP {
short d, c;
short pre[];
DP () { d = -; }
} dp[N][ << ];
struct node {
int fail;
int ch[];
} t[N];
void ins(char *s)
{
int len = strlen(s), now = root;
for(int i = ; i < len; ++i)
{
int c = s[i] - 'A';
if(!t[now].ch[c]) t[now].ch[c] = ++tot;
now = t[now].ch[c];
}
id[now] |= << (cnt++);
}
void construct_fail()
{
queue<int> q;
for(int i = ; i < ; ++i) if(t[root].ch[i]) q.push(t[root].ch[i]);
while(!q.empty())
{
int u = q.front();
q.pop();
for(int i = ; i < ; ++i)
{
int &v = t[u].ch[i];
if(!v) v = t[t[u].fail].ch[i];
else
{
t[v].fail = t[t[u].fail].ch[i];
id[v] |= id[t[v].fail];
q.push(v);
}
}
}
}
void print(int u, int S)
{
if(u == root && S == ) return;
print(dp[u][S].pre[], dp[u][S].pre[]);
printf("%c", (char)(dp[u][S].c + 'A'));
}
void solve()
{
int a = , b = , mn = 0x3f3f3f3f;
queue<int> q;
q.push();
q.push();
dp[][].d = ;
while(!q.empty())
{
int u = q.front(); q.pop();
int S = q.front(); q.pop();
if(S == ( << n) - )
{
if(dp[u][S].d < mn)
{
a = u;
b = S;
mn = dp[u][S].d;
}
continue;
}
for(int i = ; i < ; ++i) if(t[u].ch[i])
{
int v = t[u].ch[i];
dp[v][S | id[v]].c = i;
if(dp[v][S | id[v]].d == -)
{
dp[v][S | id[v]].d = dp[u][S].d + ;
dp[v][S | id[v]].pre[] = u;
dp[v][S | id[v]].pre[] = S;
q.push(v);
q.push(S | id[v]);
}
}
}
print(a, b);
}
}
int main()
{
scanf("%d", &n);
for(int i = ; i <= n; ++i)
{
scanf("%s", s);
ac_automation :: ins(s);
}
ac_automation :: construct_fail();
ac_automation :: solve();
return ;
}

bzoj1195的更多相关文章

  1. BZOJ1195 [HNOI2006]最短母串 AC自动机 bfs

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 传送门 - BZOJ1195 题意概括 给出一堆串,然后求一个包含这些串的所有串的最短的中的字典序最小的. 题解 先造一个AC ...

  2. [BZOJ1195]最短母串

    1195: [HNOI2006]最短母串 Time Limit: 10 Sec  Memory Limit: 32 MB Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最 ...

  3. BZOJ1195 HNOI2006最短母串(状压dp)

    按照子串出现的先后考虑.令f[i][j]为已经出现的字符串集合为i,最后一个出现的字符串为j时的最短串长,预处理一下任意两个串的最长重叠长度,转移显然.有点麻烦的是字典序,强行增加代码难度. 另一个比 ...

  4. [bzoj1195][HNOI2006]最短母串_动态规划_状压dp

    最短母串 bzoj-1195 HNOI-2006 题目大意:给一个包含n个字符串的字符集,求一个字典序最小的字符串使得字符集中所有的串都是该串的子串. 注释:$1\le n\le 12$,$1\le ...

  5. [bzoj1195] [hnoi2006] 最短母串

    本题是一个经典的状压dp问题,在紫书中有着加强版的例题. 本题的难度主要体现在:如何输出字符串字典序最小. 为了解决这个问题,我们有两种常用方案: 1) 我们可以采用bfs输出路径的方法,使用+1来输 ...

  6. bzoj1195 神奇的ac自动机+状态压缩dp

    /* 难的不是ac自动机,是状态压缩dp 之前做了一两题类似题目,感觉理解的还不够透彻 */ #include<iostream> #include<cstdio> #incl ...

  7. BZOJ1195[HNOI2006]最短母串——AC自动机+BFS+状态压缩

    题目描述 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. 输入 第一行是一个正整数n(n<=12),表示给定的字符串的 ...

  8. 【bzoj1195】[HNOI2006]最短母串 AC自动机+状态压缩+BFS最短路

    原文地址:http://www.cnblogs.com/GXZlegend/p/6825226.html 题目描述 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串 ...

  9. Bzoj1195 [HNOI2006]最短母串 [AC自动机]

    Time Limit: 10 Sec  Memory Limit: 32 MBSubmit: 1304  Solved: 439 Description 给定n个字符串(S1,S2,„,Sn),要求找 ...

  10. Bzoj1195 [HNOI2006]最短母串 [状态压缩]

    Time Limit: 10 Sec  Memory Limit: 32 MBSubmit: 1304  Solved: 439 Description 给定n个字符串(S1,S2,„,Sn),要求找 ...

随机推荐

  1. discuz X3.1+Apache2.2+php-5.2.17+mysql5.6.14+Discuz_X3.1

    discuz X3.1+Apache2.2.25+php-5.2.17+mysql5.6.14+Discuz_X3.1 一.准备 1.httpd-2.2.25-win32-x86-no_ssl.msi ...

  2. erlang 小程序:整数序列,搜索和为正的最长子序列

    近期学习了一下erlang, 编了个小程序 算法例如以下: 把參数分为三个 当前位置的前子序列(Save)(比方 -5, 1,2,-1, _, ... ) 当前位置为_时, 前子序列就是 1,2,-1 ...

  3. C和C++代码精粹笔记1

    CH1 更好的C 运算符重载规定,必须有一个为用户自定义类型 一些输出没注意到的函数: float x = 123.456, y = 12345; //cout.precision(2); //显示两 ...

  4. python(7)- 小程序练习:循环语句for,while实现99乘法表

    打印99乘法表 for 循环语句实现: for i in range(1,10): for j in range(1,10): print(j,"x",i,"=" ...

  5. VCC/AVCC/VDD/AVDD区别

    V*与AV*的区别是:数字与模拟的区别CC与DD的区别是:供电电压与工作电压的区别(通常VCC>VDD): 数字电路供电VCC 模拟电路供电AVCCVDD是指工作电压,就是供电进芯片的 AVDD ...

  6. bvlc_reference_caffenet.caffemodel

    #uncoding:utf-8 # set up Python environment: numpy for numerical routines, and matplotlib for plotti ...

  7. CIDR(无类域间路由)(转载)

    来源:百度百科 CIDR(无类型域间选路,Classless Inter-Domain Routing)是一个在Internet上创建附加地址的方法,这些地址提供给服务提供商(ISP),再由ISP分配 ...

  8. poj1125--Floyd

    题解: 有N个股票经济人能够互相传递消息.他们之间存在一些单向的通信路径.如今有一个消息要由某个人開始传递给其它全部人.问应该由哪一个人来传递,才干在最短时间内让全部人都接收到消息. 显然,用Floy ...

  9. UITableView基础入门

    新建一个Single View Application 添加一个空类如下: using System; using UIKit; using Foundation; namespace BasicTa ...

  10. [学些东西]用爬虫练习网站来练习burp suite

    最近看爬虫的内容.刚好看到黑板客爬虫第二关http://www.heibanke.com/lesson/crawler_ex01. ADO的i春秋课程里面提到的.另外推荐学习爬虫的好书<web ...