zoukankan      html  css  js  c++  java
  • HDU 2222 Keywords Search(AC自动机模版题)

    Keywords Search

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
    Total Submission(s): 57353    Accepted Submission(s): 18820

    Problem Description
    In the modern time, Search engine came into the life of everybody like Google, Baidu, etc.
    Wiskey also wants to bring this feature to his image retrieval system.
    Every image have a long description, when users type some keywords to find the image, the system will match the keywords with description of image and show the image which the most keywords be matched.
    To simplify the problem, giving you a description of image, and some keywords, you should tell me how many keywords will be match.
     
    Input
    First line will contain one integer means how many cases will follow by.
    Each case will contain two integers N means the number of keywords and N keywords follow. (N <= 10000)
    Each keyword will only contains characters 'a'-'z', and the length will be not longer than 50.
    The last line is the description, and the length will be not longer than 1000000.
     
    Output
    Print how many keywords are contained in the description.
     
    Sample Input
    1
    5
    she
    he
    say
    shr
    her
    yasherhs
     
    Sample Output
    3
     

    题目链接:HDU 2222

    AC自动机的模版题,有KMP的fail思想,即这条路上找不到了就跟着fail走向另外一条路,将之前的当作前缀继续进行匹配后一部分,若成功则加上这个节点的cnt,推荐一篇博客写得挺好:

    AC自动机算法 虽然感觉不是很好理解但是只能硬着头皮看……

    代码:

    #include <stdio.h>
    #include <algorithm>
    #include <cstdlib>
    #include <cstring>
    #include <bitset>
    #include <string>
    #include <stack>
    #include <cmath>
    #include <queue>
    #include <set>
    #include <map>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define LC(x) (x<<1)
    #define RC(x) ((x<<1)+1)
    #define MID(x,y) ((x+y)>>1)
    #define fin(name) freopen(name,"r",stdin)
    #define fout(name) freopen(name,"w",stdout)
    #define CLR(arr,val) memset(arr,val,sizeof(arr))
    #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
    typedef pair<int, int> pii;
    typedef long long LL;
    const double PI = acos(-1.0);
    const int N = 10010;
    const int M = 1000010;
    struct Trie
    {
        int nxt[26];
        int fail, cnt;
        void reset()
        {
            fill(nxt, nxt + 26, 0);
            fail = cnt = 0;
        }
    };
    Trie L[N * 55];
    int sz;
    char t[55], S[M];
    
    void init()
    {
        sz = 1;
        L[0].reset();
    }
    void ins(char s[])
    {
        int len = strlen(s);
        int u = 0;
        for (int i = 0; i < len; ++i)
        {
            int v = s[i] - 'a';
            if (!L[u].nxt[v])
            {
                L[sz].reset();
                L[u].nxt[v] = sz++;
            }
            u = L[u].nxt[v];
        }
        ++L[u].cnt;
    }
    namespace Aho
    {
    void build()
    {
        queue<int>Q;
        L[0].fail = -1;
        Q.push(0);
        while (!Q.empty())
        {
            int u = Q.front();
            Q.pop();
            for (int i = 0; i < 26; ++i)
            {
                int v = L[u].nxt[i];
                if (!v)
                    continue;
                Q.push(v);
                if (!u)
                    L[v].fail = 0;
                else
                {
                    int f = L[u].fail;
                    while (f != -1)
                    {
                        if (L[f].nxt[i])
                        {
                            L[v].fail = L[f].nxt[i];
                            break;
                        }
                        f = L[f].fail;
                    }
                    if (f == -1)
                        L[v].fail = 0;
                }
            }
        }
    }
    int Count(int u)
    {
        int ans = 0;
        while (u)
        {
            if (L[u].cnt)
            {
                ans += L[u].cnt;
                L[u].cnt = 0;
            }
            u = L[u].fail;
        }
        return ans;
    }
    int calc(char s[])
    {
        int ans = 0;
        int u = 0;
        int len = strlen(s);
        for (int i = 0; i < len; ++i)
        {
            int v = s[i] - 'a';
            if (L[u].nxt[v])
                u = L[u].nxt[v];
            else
            {
                int f = L[u].fail;
                while (f != -1 && L[f].nxt[v] == 0)
                    f = L[f].fail;
                if (f == -1)
                    u = 0;
                else
                    u = L[f].nxt[v];
            }
            if(L[u].cnt)
                ans += Count(u);
        }
        return ans;
    }
    }
    int main(void)
    {
        int T, n;
        scanf("%d", &T);
        while (T--)
        {
            init();
            scanf("%d", &n);
            while (n--)
            {
                scanf("%s", t);
                ins(t);
            }
            Aho::build();
            scanf("%s", S);
            printf("%d
    ", Aho::calc(S));
        }
        return 0;
    }
  • 相关阅读:
    [转]只有tcp6没有tcp问题
    Makefile 中:= ?= += =的区别
    【转】docker images 介绍
    [转]我眼中的 Docker(二)Image
    【转】一个简单的Dockerfile实例
    【转】Prometheus 介绍
    [转]MySQL索引类型按存储类型和逻辑区分
    【转】mysql索引类型
    用Unity制作游戏,你需要深入了解一下IL2CPP
    c++中CreateEvent函数
  • 原文地址:https://www.cnblogs.com/Blackops/p/6090809.html
Copyright © 2011-2022 走看看