题目描述:
题解:
先见出Trie图,然后bfs出所有状态。
我们按照字典序遍历,只要找到合法串直接跳出。这样可以保证长度最小+字典序最小。
代码:
#include<queue> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 15 int n,tot; char ch[N][55]; struct Trie { int ch[28],fl,w; }tr[650]; void trie_pic() { queue<int>q; for(int i=1;i<=26;i++) if(tr[0].ch[i]) q.push(tr[0].ch[i]); while(!q.empty()) { int u = q.front(); q.pop(); for(int i=1;i<=26;i++) { int &v = tr[u].ch[i]; if(!v) { v=tr[tr[u].fl].ch[i]; continue; } tr[v].fl = tr[tr[u].fl].ch[i]; tr[v].w|=tr[tr[v].fl].w; q.push(v); } } } struct node { int x,y; node(){} node(int x,int y):x(x),y(y){} }tp; bool vis[605][4100]; int col[2480500],fa[2480500],sta[605],tl; void bfs() { queue<node>q; q.push(node(0,0)); int f=0,sum=0; while(!q.empty()) { tp = q.front();q.pop(); int x = tp.x,y = tp.y; if(y==(1<<n)-1) { for(int i=f;i;i=fa[i]) sta[++tl]=col[i]; for(int i=tl;i>=1;i--) printf("%c",sta[i]+'A'-1); printf(" "); return ; } for(int i=1;i<=26;i++) { int v = tr[x].ch[i]; if(!vis[v][y|tr[v].w]) { vis[v][y|tr[v].w]=1; sum++; fa[sum]=f; col[sum]=i; q.push(node(v,y|tr[v].w)); } } f++; } } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%s",ch[i]+1); int u = 0,len = strlen(ch[i]+1); for(int j=1;j<=len;j++) { int c = ch[i][j]-'A'+1; if(!tr[u].ch[c])tr[u].ch[c]=++tot; u=tr[u].ch[c]; } tr[u].w|=(1<<(i-1)); } trie_pic(); bfs(); return 0; }