洛谷P2322 [HNOI2006]最短母串问题
来源:互联网 发布:阿里巴巴网络银行 编辑:程序博客网 时间:2024/06/06 00:08
链接
https://www.luogu.org/problem/show?pid=2322
题解
这道题不是傻逼题吗?
——某大佬口头禅
是傻逼题,但是我调了4节课。
一开始想的太歪了,想用状压DP(因为标签就是状压DP..),但是发现直接f[i][j][k]会炸掉。
后来又想了个很麻烦的算法得了90分,竟然是没有处理一个串是另一个串的子串的情况。(数据水到了一定程度)
最终算法:建立AC自动机,要想让长度最短,就直接BFS,状态用二元组(pos,k)表示,其中pos是AC自动机上的点的编号,k是一个状态,每一位上是0或1分别对应这个串选或没选。把(1,0)作为初始状态扔进去,然后开始BFS。
第一次碰到
这么水的题我为什么要用那么久我是不是可以退役了!
代码
//AC自动机、BFS #include <cstdio>#include <algorithm>#include <queue>#define maxn 700using namespace std;int f[maxn][1<<12], tot=1, trie[maxn][30], tail[maxn], fail[maxn], N, pre[maxn][1<<12][2], star[maxn], lt[maxn][maxn], vis[maxn][1<<12], len[maxn], table[maxn], X;char str[maxn][maxn], ans[maxn]={0,'Z'+1};queue<int> q;queue<int> qp, qk;int insert(int *s){ int pos; for(pos=1;*s;s++)pos=trie[pos][*s]?trie[pos][*s]:trie[pos][*s]=++tot; tail[pos]=1; return pos;}void acabuild(){ int f, u, now, i; q.push(1); while(!q.empty()) { now=q.front();q.pop(); for(i=1;i<=26;i++) { if(trie[now][i]) { u=trie[now][i]; for(f=fail[now];f and !trie[f][i];f=fail[f]); if(f)fail[u]=trie[f][i]; else fail[u]=1; tail[u]|=tail[fail[u]]; q.push(u); } else trie[now][i]=trie[fail[now]][i]?trie[fail[now]][i]:1; lt[now][trie[now][i]]=i; } }}void init(){ int t[maxn], i, j; scanf("%d",&N); for(i=1;i<=N;i++) { scanf("%s",str[i]+1); for(j=1;str[i][j];j++)t[j]=str[i][j]-'A'+1; t[j]=0; table[insert(t+1)]=i; } for(i=1;i<=tot;i++)if(tail[i])star[++star[0]]=i; for(i=1;i<=star[0];i++)tail[star[i]]=1<<i-1; acabuild();}void up(int &p, int &k){ int t=p; p=pre[t][k][0], k=pre[t][k][1];}void update(){ int tmp[maxn]={0}, p, k, t, flag, i, s[maxn]={0}; p=X, k=(1<<star[0])-1; for(t=p,up(p,k);p;t=p,up(p,k))s[++s[0]]=lt[p][t]; for(;str[table[t]][tmp[0]+1];)tmp[++tmp[0]]=str[table[t]][tmp[0]]; for(;s[0];s[0]--)tmp[++tmp[0]]=(char)s[s[0]]+'A'-1; for(flag=-1,i=1;flag==-1 and i<=tmp[0];i++) if(tmp[i]<ans[i])flag=1;else if(tmp[i]>ans[i])flag=0; if(flag==1){for(i=1;i<=tmp[0];i++)ans[i]=tmp[i];ans[i]=0;}}void bfs(){ int i, j, pos, k, t, x; qp.push(1);qk.push(0);vis[1][0]=0; for(i=0;i<=600;i++) { if(X)return; while(!qp.empty()) { pos=qp.front(); k=qk.front(); if(f[pos][k]!=i)break; qp.pop(),qk.pop(); if(k==(1<<star[0])-1)X=pos,update(); for(j=1;j<=26;j++) { x=trie[pos][j]; t=k;if(tail[x])t|=tail[x]; if(x==1 or vis[x][t])continue; vis[x][t]=1; f[x][t]=f[pos][k]+1; pre[x][t][0]=pos,pre[x][t][1]=k; qp.push(x),qk.push(t); } } }}int main(){ init(); bfs(); printf("%s",ans+1); return 0;}
0 0
- 洛谷P2322 [HNOI2006]最短母串问题
- BZOJ1195 HNOI2006 最短母串
- BZOJ 1195: [HNOI2006]最短母串
- 2782: [HNOI2006]最短母串
- bzoj1195: [HNOI2006]最短母串
- 【HNOI2006】bzoj1195 最短母串
- BZOJ 1195 [HNOI2006] 最短母串
- bzoj 1195 [HNOI2006]最短母串
- 【bzoj1195】[HNOI2006]最短母串
- bzoj1196[HNOI2006]公路修建问题
- 1196: [HNOI2006]公路修建问题
- [BZOJ1196] [HNOI2006]公路修建问题
- 1196: [HNOI2006]公路修建问题
- bzoj1196: [HNOI2006]公路修建问题
- BZOJ1196: [HNOI2006]公路修建问题
- 1196: [HNOI2006]公路修建问题
- bzoj1196[HNOI2006]公路修建问题
- 【BZOJ1996】【HNOI2006】公路修建问题
- ToggleButton控件的使用
- C++模板
- iOS去掉导航栏底部的线
- Java笔试中遇见奇怪问题积累篇
- hadoop集群搭建
- 洛谷P2322 [HNOI2006]最短母串问题
- iOS 之 图文混排(富文本)
- JAVA 注解的学习和对Spring注解的理解
- Spring注解@Component、@Repository、@Service、@Controller区别
- 杰米斯·哈萨比斯:创造性和直觉很重要
- KMP next
- spring-mvc 配置
- c#ispostback详解
- 背景和精灵图