bzoj1195 最短母串

状态压

  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求路径

posted @ 2018-11-24 21:12  Mr_Handsome  阅读(132)  评论(0编辑  收藏  举报