[BZOJ1195] [HNOI2006] 最短母串(AC自动机+状压bfs)

[BZOJ1195] [HNOI2006] 最短母串(AC自动机+状压bfs)

题面

给定n个字符串(S1,S2...Sn),要求找到一个最短的字符串T,使得这n个字符串都包含这个字符串
\(n \leq 12,|S| \leq 50\)

分析

在自动机上bfs,bfs的深度就是字符串长度。\(n\)很小,因此把匹配情况压成一个二进制数即可。注意还要记录前驱,方便输出方案。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<bitset> 
#define maxn 600
#define maxb (1<<12)
#define maxc 26 
using namespace std;
struct AC_automaton{
	int ch[maxn+5][maxc];
	int fail[maxn+5];
	int cnt_end[maxn+5];
	int id[maxn+5];
	int ptr;
	void insert(char *s,int num){
		int n=strlen(s+1);
		int x=0;
		for(int i=1;i<=n;i++){
			int c=s[i]-'A';
			if(!ch[x][c]) ch[x][c]=++ptr;
			x=ch[x][c];
		}
		cnt_end[x]|=(1<<(num-1));
	} 
	void get_fail(){
		queue<int>q;
		for(int i=0;i<maxc;i++) if(ch[0][i]) q.push(ch[0][i]);
		while(!q.empty()){
			int x=q.front();
			q.pop();
			
			for(int i=0;i<maxc;i++){
				if(ch[x][i]){
					fail[ch[x][i]]=ch[fail[x]][i];
					cnt_end[ch[x][i]]|=cnt_end[ch[fail[x]][i]];
					q.push(ch[x][i]);
				}else{
					ch[x][i]=ch[fail[x]][i];
				}
			}
		}
	}
	inline int size(){
		return ptr; 
	} 
}T;

int n;
char s[maxn+5];
int vis[maxn+5][maxb+5];

struct node{
	int x;
	int sta;
	int last;
	int cr;
	node(){
		
	}
	node(int _x,int _sta,int _last,int _cr){
		x=_x;
		sta=_sta;
		last=_last;
		cr=_cr;
	}
}q[maxn*maxb+5];
void bfs(){
	static char ans[maxn+5];
	int head=1,tail=0;
	q[++tail]=node(node(0,0,0,0));
	while(head<=tail){
//		printf("(%d,%d,%d,%d)\n",q[head].x,q[head].sta,q[head].last,q[head].cr);
		if(q[head].sta==(1<<n)-1){
			int sz=0;
			for(int i=head;i>0;i=q[i].last){
				ans[++sz]=q[i].cr+'A';
			}
			for(int i=sz-1;i>=1;i--) putchar(ans[i]);
			return;
		}
		for(int i=0;i<4;i++){
			int nex=T.ch[q[head].x][i];
			int ss=q[head].sta|T.cnt_end[nex];
			if(!vis[nex][ss]){
				q[++tail]=node(nex,ss,head,i);
				vis[nex][ss]=1;
			}
		}
		head++;
	}
	
}
int main(){
	int sum=0;
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%s",s+1);
		T.insert(s,i);
		sum+=strlen(s+1);
	}
	T.get_fail();
	bfs();
}

posted @ 2020-02-22 19:30  birchtree  阅读(112)  评论(0编辑  收藏  举报