hdu2896 病毒侵袭 (AC自动机)

来源:互联网 发布:兄弟连java观察者模式 编辑:程序博客网 时间:2024/06/14 21:47

只在每个模式串最后记录模式串的顺序号,中间全设为0即可,然后AC自动机跑一遍。

#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include <algorithm>#include <queue>#include <malloc.h>using namespace std;#define maxn 94bool vis[550];struct Trie{    Trie *fail;    Trie *next[maxn];    int num;    Trie()    {        for(int i=0;i<maxn;i++)            next[i]=NULL;        fail=NULL;        num=0;    }}*root;void inserttrie(char *str,int k){    Trie *p=root;    for(int i=0;str[i]!='\0';i++)    {        int id=str[i]-' ';        if(p->next[id]==NULL)        {            p->next[id]=new Trie;        }        p=p->next[id];    }    p->num=k;}void buildfail(){    Trie *son,*temp,*p=root;    queue<struct Trie*>que;    que.push(p);    while(!que.empty())    {        temp=que.front();        que.pop();        for(int i=0;i<maxn;i++)        {            son=temp->next[i];            if(son!=NULL)            {                if(temp==root)son->fail=root;                else                {                    p=temp->fail;                    while(p)                    {                        if(p->next[i])                        {                            son->fail=p->next[i];                            break;                        }                        p=p->fail;                    }                    if(!p)                        son->fail=root;                }                que.push(son);            }        }    }}int querry(char *str){    int ans=0;    Trie *p,*temp;    p=root;    int len=strlen(str);    for(int i=0;i<len;i++)    {        int id=str[i]-' ';        while(p!=root&&p->next[id]==NULL)p=p->fail;        p=p->next[id];        if(!p)p=root;        temp=p;        while(temp!=root)        {            vis[temp->num]=1;   /*设置vis,模式串全走完了,即在主串中,则令模式串顺序号为vis的下标,并改成1,方便统计*/            if(temp->num!=0)            {                ans++;            }            temp=temp->fail;        }    }    return ans;}int main(){    int n,m,i;    char st[330],web[10100];    int total=0,flag;    root=new Trie;    scanf("%d",&n);    for(i=1;i<=n;i++)    {        scanf("%s",st);        inserttrie(st,i);    }    buildfail();    scanf("%d",&m);    for(i=1;i<=m;i++)    {        scanf("%s",web);        memset(vis,0,sizeof(vis));        flag=querry(web);        if(flag!=0)        {            total++;            printf("web %d:",i);            for(int j=1;j<=n;j++)            {                if(vis[j])                    printf(" %d",j);            }            printf("\n");        }    }    printf("total: %d\n",total);    return 0;}
0 0
原创粉丝点击