BZOJ1195 HNOI2006 最短母串

来源:互联网 发布:顾家北和慎小嶷 知乎 编辑:程序博客网 时间:2024/06/05 15:46

非主流做法 , 此题就不提示了。

看到此题 , Fuxey的第一感觉 , 这玩意我以前见过啊 , AC自动机上的动态规划。 中午回学校啪啪敲了一份AC自动机上的状压DP。

WA WA WA

然后检查 , 代码。 起初我认为同层(即同一个状态S) 互相影响并不会更优 , 所以不会影响答案, 然而需要考虑同层的转化。
不要紧 , Dijkstra上

TLE……

然而n^2的Dijkstra并不能过 , 优先队列优化一下呗。 然而A了……

(Fuxey建议大家还是写主流的状压DP写法 , 除非想练写AC自动机 )

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <vector>#include <deque>#include <queue>#include <set>#include <map>#include <queue>#include <algorithm>#include <stack>#include <cassert>using namespace std;const int maxn = 12;const int maxlen = 51;const int sigmaSize = 26;const int INF = 0x3f3f3f3f;const int maxnode = maxlen*maxn;int n;char s[maxlen];int d[maxnode][1<<maxn] , loop[maxnode][1<<maxn];int pre[maxnode][1<<maxn];__inline int id(char c) { return c-'A'; } struct ACaut{    int n;    queue<int> q;    int g[maxnode][sigmaSize];    int mark[maxnode] , v[maxnode] , f[maxnode];    vector<int> l[maxnode] , r[maxnode]; int book[maxnode];    void init() { n = 0; }    void add(int num)    {        int len = strlen(s) , u = 0;        for(int i=0;i<len;i++)        {            int c = id(s[i]);            if(!g[u][c])            {                g[u][c] = ++n;                mark[n] = f[n] = 0;                memset(g[n] , 0 , sizeof(g[n]));            }            u = g[u][c];        }        mark[u] |= 1<<(num-1);    }    void getFail()    {        mark[0] = v[0] = f[0] = 0;        for(int i=0;i<sigmaSize;i++)        {            int t = g[0][i];            if(!t) continue;            q.push(t);            if(mark[t]) v[t] = mark[t];        }        while(!q.empty())        {            int now = q.front(); q.pop();            for(int i=0;i<sigmaSize;i++)            {                int t = g[now][i] , j;                if(!t)                {                    g[now][i] = g[f[now]][i];                    continue;                }                else q.push(t);                for(j=f[now];j && !g[j][i];j = f[j]) ;                f[t] = g[j][i]?g[j][i]:0;                v[t] = v[f[t]];                if(mark[t]) v[t] |= mark[t];            }        }    }    void dpInit()    {        for(int i=0;i<=n;i++)  memset(d[i] , -1 , sizeof(d[i]));    }     void dp(int s)    {        if(s==(1<<::n)-1) { for(int i=0;i<=n;i++) d[i][s] = 0; return; }        for(int i=0;i<=n;i++) l[i].clear() , r[i].clear();        for(int u=0;u<=n;u++)        {            int& now = d[u][s] = INF; book[u] = 0;            for(int i=0;i<sigmaSize;i++)            {                int t = g[u][i];                if((s|v[t]) == s && t!=u) l[t].push_back(u) , r[t].push_back(i);                else if(d[t][s|v[t]]+1 < now) now = d[t][s|v[t]]+1 , pre[u][s] = i;            }        }        priority_queue<pair<int, int> > pq;        for(int i=0;i<=n;i++) if(d[i][s]!=INF) pq.push(make_pair(-d[i][s], i));        while(pq.size())        {            int now = pq.top().second , v = -pq.top().first; pq.pop();            if(d[now][s]!=v) continue;            for(int i=0;i<l[now].size();i++)            {                int k = l[now][i];                if(d[k][s] > v+1 || (d[k][s]==v+1 && pre[k][s] > r[now][i]))                {                    pre[k][s] = r[now][i];                      if(d[k][s] == v+1)  continue;                    d[k][s] = v+1;                    pq.push(make_pair(-d[k][s], k));                }            }        }    }    void print()    {        int s = 0;        for(int i=0 , j=1;j<=d[0][0];j++)        {            printf("%c" , 'A'+pre[i][s]);            i = g[i][pre[i][s]];            s |= v[i];        }    }}solver;int main(){       cin>>n;    solver.init();    for(int i=1;i<=n;i++)    {        scanf("%s" , s);        solver.add(i);    }       solver.getFail();       for(int i=(1<<n)-1;i>=0;i--) solver.dp(i);    solver.print(  );    return 0;}

附上最卡时限的数据:
TestData 9:

Input:12AABBBABBBBBAAAAABABBBAAABBABBAABABAABAAABAAAAAABBBAAABABBBABBBABABAABAABABBBBABBBAABBABBBBABAABABBBABABABBBAAABBABBBABAABBBAAABABBABBBABBBAABBABABBABBBAAABABAABBAABBAABAAABAABBBBBABBBBBAABBBBABBBBBBABAAAAABAAABAABBBBBABBAABAABBAAABABBBAAABBBBBABAABABBBBBABBAABAABBAAABABBBAAABBBBBABAABAAAAABBBBBABBAAABABAABBAABAABAAABABBBBBABBBABAAAAAABBAAABBBAAABABBBAAABABBABBBAAAABBBBAAAAABBBBABBBBABBAABAAABAAABAAABABBBAAABBBBBABAABAAAAABBBBBABABABBAAABABABBBAABBBBABABBAABABABBBBBBBBABAAABABAAAAA
Output:BAABAAABABBBBBABBBABAAAAAABBAAABBBAAABABBBABBBABABAABAABABBBBABBBAABBABABBABBBAAABABAABBAABAAABAABBBBBABBBBBAABBBBABBBBBBABAAAAABAABBBBBABBAABAABBAAABABBBAAABBBBBABAABAAAAABBBBBABABABBAAABABABBAABBBBABABBAABABABBBBBBBBABAAABABAAAAABBBBABAABABBBABABABBBAAABBABBBABAABBBAAABABBABBBAAAABBBBAAAAABBBBABBBBABBAABAAABAAABBBABBBBBAAAAABABBBAAABBABBAABABAABAAABAAA
0 0
原创粉丝点击