在
A
C
AC
AC自动机上
b
f
s
bfs
bfs即可。用
v
i
s
[
i
d
]
[
s
t
a
t
e
]
vis[id][state]
vis[id][state]表示当前处于
A
C
AC
AC自动机上
i
d
id
id号节点,已包含串的状态为
s
t
a
t
e
state
state。由于是
b
f
s
bfs
bfs,所以可以保证第一次搜到的即为最短的。搜到包含所有串的状态输出即可。
要把一个节点的
f
a
i
l
fail
fail的贡献加到该节点身上。
#include<bits/stdc++.h>
#define cs const
#define re register
#define pii pair<int,int>
#define mp make_pair
#define fi first
#define se second
using namespace std;
cs int N=12,L=51,alpha=26;
int n,tot=0;char s[L];
struct node{int son[alpha],fail,val;}a[N*L];
inline void insert(char *s,int id){
int now=0,len=strlen(s);
for(int re i=0;i<len;++i){
if(!a[now].son[s[i]-'A'])
a[now].son[s[i]-'A']=++tot;
now=a[now].son[s[i]-'A'];
}a[now].val|=(1<<(id-1));
}
inline void build_fail(){
queue<int> Q;
for(int i=0,v;i<alpha;++i)
if(v=a[0].son[i]) Q.push(v),a[v].fail=0;
while(!Q.empty()){
int u=Q.front();Q.pop();
a[u].val|=a[a[u].fail].val;
for(int re i=0,v;i<alpha;++i)
if(v=a[u].son[i]) a[v].fail=a[a[u].fail].son[i],Q.push(v);
else a[u].son[i]=a[a[u].fail].son[i];
}
}
int S,ans[N*L][1<<N];
bool vis[N*L][1<<N];
pii pre[N*L][1<<N];
inline void print(cs pii &U){
if(!(U.fi+U.se)) return;
print(pre[U.fi][U.se]);
putchar(ans[U.fi][U.se]+'A');
}
inline void bfs(){
queue<pii> Q;Q.push(mp(0,0)),vis[0][0]=1;
while(!Q.empty()){
pii U=Q.front();Q.pop();
int u=U.fi,s=U.se;
if(s==S){print(U);puts("");return;}
for(int i=0,v,t;i<alpha;++i){
if(vis[v=a[u].son[i]][t=s|a[v].val]) continue;
pre[v][t]=U,ans[v][t]=i,vis[v][t]=1,Q.push(mp(v,t));
}
}
}
int main(){
// freopen("1980.in","r",stdin);
scanf("%d",&n),S=(1<<n)-1;
for(int i=1;i<=n;++i)
scanf("%s",s),insert(s,i);
build_fail(),bfs();
}