1. 程式人生 > >bzoj1195 最短母串

bzoj1195 最短母串

spa 路徑 cstring scan queue == namespace span ret

狀態壓

  1 #include<queue>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6 int n,m,pth,sta,tot;
  7 int ed[605];
  8 int vl[605];
  9 char ans[605];
 10 bool vis[605][1<<12];
 11 char s[55];
 12 struct Trie{
 13     int
son[26]; 14 int fail; 15 }tr[605]; 16 struct node{ 17 int u; 18 int sta; 19 node(){} 20 node(int u,int sta):u(u),sta(sta){} 21 }; 22 int dis[605][1<<12]; 23 void build(char b[],int mk){ 24 int len=strlen(b+1); 25 int now=0; 26 for(int i=1;i<=len;i++){
27 int k=b[i]-A; 28 if(!tr[now].son[k])tr[now].son[k]=++tot; 29 now=tr[now].son[k];vl[now]=min(vl[now],len-i); 30 } 31 ed[now]|=1<<(mk-1); 32 } 33 void getfail(){ 34 queue<int>que; 35 for(int i=0;i<26;i++){ 36 if(tr[0].son[i]){
37 que.push(tr[0].son[i]); 38 } 39 } 40 while(!que.empty()){ 41 int u=que.front(); 42 que.pop(); 43 for(int i=0;i<26;i++){ 44 if(tr[u].son[i]){ 45 tr[tr[u].son[i]].fail=tr[tr[u].fail].son[i]; 46 ed[tr[u].son[i]]|=ed[tr[tr[u].fail].son[i]]; 47 que.push(tr[u].son[i]); 48 } 49 else tr[u].son[i]=tr[tr[u].fail].son[i]; 50 } 51 } 52 } 53 void get_len(){ 54 queue<node>que;pth=0x3f3f3f3f; 55 memset(dis,0x3f,sizeof(dis)); 56 que.push(node(0,0));dis[0][0]=0; 57 vis[0][0]=true; 58 while(!que.empty()){ 59 node s=que.front(); 60 que.pop();vis[s.u][s.sta]=false; 61 for(int i=0;i<26;i++){ 62 int v=tr[s.u].son[i]; 63 if(dis[v][s.sta|ed[v]]>dis[s.u][s.sta]+1){ 64 dis[v][s.sta|ed[v]]=dis[s.u][s.sta]+1; 65 if(!vis[v][s.sta|ed[v]]){ 66 vis[v][s.sta|ed[v]]=true; 67 que.push(node(v,s.sta|ed[v])); 68 } 69 } 70 } 71 } 72 for(int i=0;i<=tot;i++){ 73 pth=min(dis[i][sta],pth); 74 } 75 } 76 void dfs(int now,int state,int dep){ 77 if(state==sta){ 78 if(dep!=pth+1)return; 79 for(int i=1;i<=pth;i++){ 80 printf("%c",ans[i]); 81 } 82 printf("\n"); 83 exit(0); 84 } 85 if(dep>pth)return; 86 for(int i=0;i<26;i++){ 87 int v=tr[now].son[i]; 88 if(dis[v][state|ed[v]]==dis[now][state]+1){ 89 ans[dep]=i+A; 90 dfs(v,state|ed[v],dep+1); 91 } 92 } 93 } 94 int main(){ 95 scanf("%d",&n);sta=(1<<n)-1; 96 for(int i=1;i<=n;i++){ 97 scanf("%s",s+1); 98 build(s,i); 99 } 100 getfail();get_len(); 101 dfs(0,0,1); 102 return 0; 103 }

縮求最短路,再dfs求路徑

bzoj1195 最短母串