zoukankan      html  css  js  c++  java
  • bzoj1195

    AC自动机+状压dp

    多串匹配要想ac自动机

    dp[i][S]表示在i状态选中S

    转移就用bfs,每个点通过fail收集信息,不要忘记通过fail传递

    昨天搞不明白为什么自动机每次只可以转移儿子,不可以转移fail,问了问大概知道因为儿子是最长的后缀,包含的信息最多,包含了其他fail的信息,就相当于收集了其他fail的东西,就不用走了,但是一定要收集,这跟kmp很像,kmp就是走最大的后缀,这里也是,这样就可以保证不遗补漏同时加速

    字典序最大在bfs时已经保证了,感觉比较显然,每次先拓展字典序最小的字符,bfs又求最短路,正好保证了字典序最小

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 605;
    int n;
    char s[N];
    namespace ac_automation 
    {
        int cnt, root, tot;
        int id[N];
        struct DP {
            short d, c; 
            short pre[2];
            DP () { d = -1; }
        } dp[N][1 << 12];
        struct node {
            int fail;
            int ch[26];
        } t[N];
        void ins(char *s)
        {
            int len = strlen(s), now = root;
            for(int i = 0; i < len; ++i) 
            {
                int c = s[i] - 'A';
                if(!t[now].ch[c]) t[now].ch[c] = ++tot;
                now = t[now].ch[c];
            }
            id[now] |= 1 << (cnt++);
        }
        void construct_fail() 
        {
            queue<int> q;
            for(int i = 0; i < 26; ++i) if(t[root].ch[i]) q.push(t[root].ch[i]);
            while(!q.empty())
            {
                int u = q.front();
                q.pop();
                for(int i = 0; i < 26; ++i) 
                {
                    int &v = t[u].ch[i];
                    if(!v) v = t[t[u].fail].ch[i];
                    else
                    {
                        t[v].fail = t[t[u].fail].ch[i];
                        id[v] |= id[t[v].fail];
                        q.push(v);
                    }
                }
            }
        }
        void print(int u, int S) 
        {
            if(u == root && S == 0) return;
            print(dp[u][S].pre[0], dp[u][S].pre[1]);
            printf("%c", (char)(dp[u][S].c + 'A'));
        }
        void solve()
        {
            int a = 0, b = 0, mn = 0x3f3f3f3f;
            queue<int> q;
            q.push(0);
            q.push(0);
            dp[0][0].d = 0;
            while(!q.empty())
            {
                int u = q.front(); q.pop();
                int S = q.front(); q.pop();
                if(S == (1 << n) - 1) 
                {
                    if(dp[u][S].d < mn) 
                    {
                        a = u;
                        b = S;
                        mn = dp[u][S].d; 
                    }
                    continue;
                }
                for(int i = 0; i < 26; ++i) if(t[u].ch[i])
                {
                    int v = t[u].ch[i];
                    dp[v][S | id[v]].c = i;
                    if(dp[v][S | id[v]].d == -1) 
                    {
                        dp[v][S | id[v]].d = dp[u][S].d + 1;
                        dp[v][S | id[v]].pre[0] = u;
                        dp[v][S | id[v]].pre[1] = S; 
                        q.push(v);
                        q.push(S | id[v]);
                    }
                }
            }     
            print(a, b);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
        }
    }
    int main()
    {
        scanf("%d", &n);
        for(int i = 1; i <= n; ++i)
        {
            scanf("%s", s);
            ac_automation :: ins(s);
        }
        ac_automation :: construct_fail();
        ac_automation :: solve();
        return 0;
    }
    View Code
  • 相关阅读:
    0309. Best Time to Buy and Sell Stock with Cooldown (M)
    0621. Task Scheduler (M)
    0106. Construct Binary Tree from Inorder and Postorder Traversal (M)
    0258. Add Digits (E)
    0154. Find Minimum in Rotated Sorted Array II (H)
    0797. All Paths From Source to Target (M)
    0260. Single Number III (M)
    0072. Edit Distance (H)
    0103. Binary Tree Zigzag Level Order Traversal (M)
    0312. Burst Balloons (H)
  • 原文地址:https://www.cnblogs.com/19992147orz/p/8041134.html
Copyright © 2011-2022 走看看