HDU 2896 病毒侵袭(AC自动机)

来源:互联网 发布:淘宝补差价链接买东西 编辑:程序博客网 时间:2024/06/05 04:41

HDU 2896 病毒侵袭(AC自动机)

http://acm.hdu.edu.cn/showproblem.php?pid=2896

题意:

        给你一组模板,然后在给你多个文本,要你去匹配文本,看看每个文本中都出现了哪些模板然后输出即可.

分析:

        本题的模板不会重复,题目中已说明.

        不过本题的字符是所有ASCII码可见字符,所以sigma_size=128.

AC代码:

#include<queue>#include<set>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>using namespace std;const int maxnode=100000+100;const int sigma_size=128;struct AC_Automata{    int ch[maxnode][sigma_size];    int val[maxnode];//表示单词节点的编号    int f[maxnode];    int last[maxnode];    int sz;    void init()    {        sz=1;        memset(ch[0],0,sizeof(ch[0]));        val[0]=f[0]=last[0]=0;    }    void insert(char *s,int v)    {        int n=strlen(s),u=0;        for(int i=0;i<n;i++)        {            int id=s[i];            if(ch[u][id]==0)            {                ch[u][id]=sz;                memset(ch[sz],0,sizeof(ch[sz]));                val[sz++]=0;            }            u=ch[u][id];        }        val[u]=v;    }    void print(int i,set<int> &st)    {        if(val[i])        {            if( st.find(i)==st.end() ) st.insert(val[i]);            print(last[i],st);        }    }    void find(char *s,set<int> &st)//st集合用来保存文本串s已经匹配到的模式串编号    {        int n=strlen(s),j=0;        for(int i=0;i<n;i++)        {            int id=s[i];            while(j && ch[j][id]==0) j=f[j];            j=ch[j][id];            if(val[j]) print(j,st);            else if(last[j]) print(last[j],st);        }    }    void getFail()    {        f[0]=0;        queue<int> q;        for(int i=0;i<sigma_size;i++)        {            int u=ch[0][i];            if(u)            {                last[u]=f[u]=0;                q.push(u);            }        }        while(!q.empty())        {            int r=q.front();q.pop();            for(int i=0;i<sigma_size;i++)            {                int u=ch[r][i];                if(!u) continue;                q.push(u);                int v=f[r];                while(v && ch[v][i]==0) v=f[v];                f[u]=ch[v][i];                last[u] = val[f[u]]?f[u]:last[f[u]];            }        }    }};AC_Automata ac;int n,m;char word[200+10];char text[10000+10];set<int>::iterator it;int main(){    while(scanf("%d",&n)==1&&n)    {        ac.init();        for(int i=1;i<=n;i++)        {            scanf("%s",word);            ac.insert(word,i);        }        ac.getFail();        int total=0;        scanf("%d",&m);        for(int i=1;i<=m;i++)        {            scanf("%s",text);            set<int> st;            ac.find(text,st);            if(st.size()>0)            {                printf("web %d:",i);                total++;                for(it=st.begin();it!=st.end();it++)                    printf(" %d",(*it) );                printf("\n");            }        }        printf("total: %d\n",total);    }    return 0;}


0 0
原创粉丝点击