BZOJ 1195: [HNOI2006]最短母串

来源:互联网 发布:魔兽70数据库 编辑:程序博客网 时间:2024/06/05 23:52

一看字符串就想到ac自动机是不是没救了

然后决定在AC自动机上做分层图最短路233333333

结果发现极限数据刚好卡时限了QAQ

仔细一想好像每条边的长度都是1哎。

果断BFS

其实DFS应该也可以的吧,而且可以剪枝。

但是我有DFS恐惧症,于是果断选择了BFS。

结果跑得奇慢无比。。。。。。。。

不谈了

我想静静

#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include<algorithm>using namespace std;const int inf=1e9;struct Node{int fail,ch[26],val;void clear(){fail=val=0;memset(ch,0,sizeof(ch));}}tr[605];int sz;int bin[20],n;void insert(char *s,int val){int u=0,len=strlen(s);for(int i=0;i<len;i++){int c=s[i]-'A';if(!tr[u].ch[c]){tr[u].ch[c]=++sz;tr[sz].clear();}u=tr[u].ch[c];}tr[u].val|=bin[val];}void build(){queue<int>q;q.push(0);while(!q.empty()){int u=q.front();q.pop();for(int i=0;i<26;i++){if(tr[u].ch[i]){int v=tr[u].ch[i];if(u)tr[v].fail=tr[tr[u].fail].ch[i];q.push(v);}else tr[u].ch[i]=tr[tr[u].fail].ch[i];}}}int fromu[605][4100],froms[605][4100];bool vis[605][4100];void print(int u,int s){if(!u)return;print(fromu[u][s],froms[u][s]);for(int i=0;i<26;i++){int v=tr[fromu[u][s]].ch[i],t=froms[u][s];for(int p=v;p;p=tr[p].fail)t|=tr[p].val;if(v==u&&t==s){putchar('A'+i);break;}}}void bfs(){queue<int>q1,q2;q1.push(0);q2.push(0);vis[0][0]=1;while(!q1.empty()){int u=q1.front(),s=q2.front();q1.pop();q2.pop();for(int i=0;i<26;i++){int v=tr[u].ch[i],t=s;for(int p=v;p;p=tr[p].fail)t|=tr[p].val;if(!vis[v][t]){vis[v][t]=1;q1.push(v);q2.push(t);fromu[v][t]=u;froms[v][t]=s;if(t==bin[n+1]-1){print(v,t);return;}}}}}char s[55];int main(){//freopen("a.in","r",stdin);//freopen("a.out","w",stdout);scanf("%d",&n);tr[sz=0].clear();bin[1]=1;for(int i=2;i<20;i++)bin[i]=bin[i-1]<<1; for(int i=1;i<=n;i++){scanf("%s",s);insert(s,i);}build();bfs();return 0;}


0 0