1. 程式人生 > >bzoj 1195: [HNOI2006]最短母串

bzoj 1195: [HNOI2006]最短母串

bool string class pan urn make second style efi

MEL卡空間幹嘛。。。

不過代碼應該沒有問題

/*
    建立AC自動機 
    然後按照字典序跑bfs
    直到找到組合要求的字符串 
*/
#include<queue> 
#include<cstdio>
#include<cstring>
#define mp make_pair
using namespace std;
const int N=2500050;
int n,tot,fa[N],a[N];
bool b[1005][1<<12];
struct tree 
{
    int son[26],id,now,nxt;
    tree()
    {
        
for(int i=0;i<26;i++) son[i]=0; id=now=nxt=0; } } f[N]; void insert(char*s,int k) { int len=strlen(s+1),u=0; for(int i=1;i<=len;i++) { int v=s[i]-A; if(!f[u].son[v]) f[u].son[v]=++tot,f[u].id=tot; u=f[u].son[v]; } f[u].now
=(1<<k)>>1; } void ac() { queue< int > q; for(int i=0;i<26;i++) if(f[0].son[i]) q.push(f[0].son[i]); while(!q.empty()) { int u=q.front();q.pop(); for(int i=0;i<26;i++) if(f[u].son[i]) f[f[u].son[i]].nxt
=f[f[u].nxt].son[i], q.push(f[u].son[i]); else f[u].son[i]=f[f[u].nxt].son[i]; int v=f[u].nxt; while(v&&f[v].now==0) v=f[v].nxt; f[u].now|=f[v].now;// 找一個最近的後綴就可以包含所有後綴 } } void print(int x) { if(!x) return ; print(fa[x]); putchar(A+a[x]); } void solve() { queue< pair< int,pair< int,int > > > q; q.push(mp(0,mp(f[0].now,0))); b[0][f[0].now]=1; while(!q.empty()) { pair< int,pair< int,int > > x=q.front();q.pop(); int id=x.second.second; int now=x.second.first; int u=x.first; if(now==(1<<n)-1) {print(id);return ;} for(int i=0;i<26;i++) { int k=now|f[f[u].son[i]].now; if(b[f[f[u].son[i]].id][k]) continue; b[f[f[u].son[i]].id][k]=1; fa[++tot]=id;a[tot]=i; q.push(mp(f[u].son[i],mp(k,tot))); } } } int main() { scanf("%d",&n) ; char s[100]; for(int i=1;i<=n;i++) scanf("%s",s+1),insert(s,i); ac(); solve(); return 0; }

bzoj 1195: [HNOI2006]最短母串