HDU-2896-AC自动机

来源:互联网 发布:foursquare数据集下载 编辑:程序博客网 时间:2024/06/06 01:52

题目大意:很裸的AC自动机,就是要按照模式串的先后顺序输出;

题目解析:只需要在tire树上每个节点加上一个end,表示当前结束的是哪一个模式串,之后query的时候记录下来,最后扫一遍O(n);

AC代码:

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <queue>using namespace std;const int N = 510;const int maxn=210;const int maxm=128;struct Trie{    int next[maxn*N][maxm],fail[N*maxn],end[N*maxn];    int root,L;    int newnode()    {        for(int i = 0;i < 128;i++)            next[L][i] = -1;        end[L++] = -1;        return L-1;    }    void init()    {        L = 0;        root = newnode();    }    void insert(char s[],int id)    {        int len = strlen(s);        int now = root;        for(int i = 0;i < len;i++)        {            if(next[now][s[i]] == -1)                next[now][s[i]] = newnode();            now=next[now][s[i]];        }        end[now]=id;    }    void build()    {        queue<int>Q;        fail[root] = root;        for(int i = 0;i < 128;i++)            if(next[root][i] == -1)                next[root][i] = root;            else            {                fail[next[root][i]] = root;                Q.push(next[root][i]);            }        while(!Q.empty())        {            int now = Q.front();            Q.pop();            for(int i = 0;i < 128;i++)                if(next[now][i] == -1)                    next[now][i] = next[fail[now]][i];                else                {                    fail[next[now][i]] = next[fail[now]][i];                    Q.push(next[now][i]);                }        }    }    bool used[510];    bool query(char buf[],int n,int id)    {        int len = strlen(buf);        int now = root;        memset(used,false,sizeof(used));        bool flag = false;        for(int i = 0;i < len;i++)        {            now = next[now][buf[i]];            int temp = now;            while(temp != root)            {                if(end[temp] != -1)                {                    used[end[temp]] = true;                    flag = true;                }                temp = fail[temp];            }        }        if(!flag)return false;        printf("web %d:",id);        for(int i = 1;i <= n;i++)            if(used[i])                printf(" %d",i);        printf("\n");        return true;    }};char buf[10010];Trie ac;int main(){    int n,m;    while(scanf("%d",&n) != EOF)    {        ac.init();        for(int i = 1;i <= n;i++)        {            scanf("%s",buf);            ac.insert(buf,i);        }        ac.build();        int ans = 0;        scanf("%d",&m);        for(int i = 1;i <= m;i++)        {            scanf("%s",buf);            if(ac.query(buf,n,i))                ans++;        }        printf("total: %d\n",ans);    }    return 0;}


原创粉丝点击