zoukankan      html  css  js  c++  java
  • POJ1699 HDU 1560 Best Sequence(AC自动机 最短路)

    曾写过迭代加深搜索的方法,现在使用在AC自动上跑最短路的方法

    dp[i][j]表示状态为到节点i,模式串是否包含的状态为j的最短串的长度,则状态转移方程为:

    dp[nx][ny] = min(dp[x][y] + 1) , 其中nx为x后继结点,ny为从y转移过来的新状态,更新时加入队列

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<set>
    #include<string>
    using namespace std;
    
    int Hash[128];
    typedef long long LL;
    
    const int N = 150, CH = 4, INF = 0x3F3F3F3F;
    int n, cnt;
    struct Trie{
        Trie *next[CH];
        Trie *fail;
        int id;
    }tree[N], *q[50000];
    
    int chi[N][CH];
    int sum[N];
    int dp[N][1024];
    bool inq[N][1024];
    
    class ACauto{
        private:
            int nxt;
            Trie *root;
    
        public:
        ACauto(){
            root = &tree[0];
            nxt=0;
            memset(&tree[0], 0, sizeof(Trie));
        }
    
        void insert(string s, int id){
            Trie *p = root;
            for(int i = 0; i < s.size(); i++){
                int c = Hash[s[i]];
                if(!p -> next[c]){
                    memset(&tree[++nxt], 0, sizeof(Trie));
                    p -> next[c] = &tree[nxt];
                    p -> next[c] -> id = nxt;
                }
                p = p -> next[c];
            }
            sum[p->id] = 1 <<id;
        }
    
        void build(){
            int front = 0, rear = 0;
            q[rear++] = root;
            root -> fail = NULL;
            while(front < rear){
                Trie *cur = q[front++];
    
                if(cur -> fail){
                    sum[cur->id] |= sum[cur->fail ->id];
                }
    
                for(int i = 0; i < CH; i++){
    
                    Trie *son = cur -> next[i];
                    Trie *tp = (cur == root)? root: cur -> fail->next[i];
                    if(son == NULL){
                        cur -> next[i] = tp;
                    }else{
                        son -> fail = tp;
                        q[rear++] = son;
                    }
                    son = cur -> next[i];
                    chi[cur->id][i] = son->id;
                }
            }
        }
    
        void solve(){
            memset(dp, 0x3F, sizeof(dp));
            memset(inq, 0, sizeof(inq));
            queue<int> q;
            dp[0][0] = 0;
            inq[0][0] = 1;
            int st = 1 << cnt;
            q.push(0);
            while(!q.empty()){
                int u = q.front();
                q.pop();
                int x = u / st;
                int y = u % st;
                inq[x][y] = 0;
                for(int i = 0 ; i < CH; i++){
                    int nx  = chi[x][i], ny = y | sum[chi[x][i]];
                    if(dp[nx][ny] > dp[x][y] + 1){
                        dp[nx][ny] = dp[x][y] + 1;
                        if(!inq[nx][ny]){
                            q.push(nx * st + ny);
                            inq[nx][ny] = 1;
                        }
                    }
                }
            }
            int ans = INF;
            for(int i = 0; i <= nxt; i++){
                ans = min(ans, dp[i][st - 1]);
            }
            printf("%d
    ", ans);
    
        }
    
    };
    
    char str[100];
    int main(){
        Hash['A'] = 0;
        Hash['C'] = 1;
        Hash['G'] = 2;
        Hash['T'] = 3;
        int t;
        cin>>t;
        while(t--){
            int n;
            cin>>n;
            set<string> st;
            for(int i = 0; i < n; i++){
                string str;
                cin>>str;
                st.insert(str);
            }
            ACauto ac;
            memset(sum, 0, sizeof(sum));
    
            cnt = 0;
            for(set<string>::iterator it = st.begin(); it != st.end(); it++){
                ac.insert(*it, cnt++);
            }
            ac.build();
            ac.solve();
        }
    
        return 0;
    }
    

      

  • 相关阅读:
    bzoj1051(明星奶牛)
    hdu4081(秦始皇的道路系统)
    bzoj2330(差分约束)
    JPA & Hibernate 注解
    Hibernate中对象的3种状态:瞬时态、持久态、脱管态
    Spring Data JAP 多个不是必填的查询条件处理
    设计模式
    Java远程方法调用(RMI)
    Javascript注意事项四【提高循环性能的策略】
    Javascript注意事项三【使用假值】
  • 原文地址:https://www.cnblogs.com/IMGavin/p/5815719.html
Copyright © 2011-2022 走看看