读书人

[AC自动机]hdoj 2896:病毒袭击

发布时间: 2012-12-18 12:43:41 作者: rapoo

[AC自动机]hdoj 2896:病毒侵袭

大致题意:
? ? 给出n个模式串,m个文本串。对于每个文本串,求出哪些模式串在这个文本串中出现过。最后求出能够包含模式串的文本串总数。

?

大致思路:

? ? ac自动机模版的小小变形,要注意字符集是所有128个ASCII码可见字符。这道题用静态字典树的优化效果并不明显。

?

#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#include <algorithm>using namespace std;const int inf=1<<28;const int nMax=500;const int mMax=500005;class node{public:    int id;    int vis;  //前缀记录标志    node *next[130],*fail;}*root,*que[mMax],num[500000];bool vist[mMax];int x,cnt;node *newnode(){    node * p = num + x++;    for(int i = 0; i <130; i++){        p->next[i] = NULL;    }    p->id=-1;    p->fail=NULL;    p->vis=0;    return p;}void insert(char *s){    //构造前缀树    int i;    node *r=root;    int l=strlen(s);    for(i=0;i<l;i++){        int loc=s[i];        if(r->next[loc]==NULL){            r->next[loc]=newnode();        }        r=r->next[loc];    }    if(r->id==-1)r->id=cnt++;    r->vis++;}void acAuto(){      //用bfs为每个节点设定fail指针    int i,head=0,tail=0;    node *p,*tmp;    root->fail=NULL;    que[tail++]=root;    while(head<tail){        tmp=que[head++];        for(i=0;i<130;i++){            if(tmp->next[i]==NULL)continue;            if(tmp==root){                tmp->next[i]->fail=root;            }            else {                for(p=tmp->fail;p!=NULL;p=p->fail){                    if(p->next[i]!=NULL){                        tmp->next[i]->fail=p->next[i];                        break;                    }                }                if(p==NULL){                    tmp->next[i]->fail=root;                }            }            que[tail++]=tmp->next[i];        }    }}int search(char *msg){    int i,idx,ans=0;    node *p=root,*tmp;    for(i=0;msg[i];i++){        idx=msg[i];        while(p->next[idx]==NULL&&p!=root){            p=p->fail;        }        p=p->next[idx];        if(p==NULL)p=root;        for(tmp=p;tmp!=NULL;tmp=tmp->fail){//&&tmp->vis!=-1           // ans+=tmp->vis;            tmp->vis=-1;            if(tmp->id!=-1){                ans=1;                vist[tmp->id]=1;            }        }    }    return ans;}int main(){    int n,m,i,sum;    char str[502],text[10002];    while(scanf("%d",&n)!=EOF){        x=0;        sum=0;        cnt=1;        root=newnode();        for(i=0;i<n;i++){            scanf("%s",str);            insert(str);        }        acAuto();        scanf("%d",&m);        for(i=1;i<=m;i++){            memset(vist,0,sizeof(vist));            scanf("%s",text);            if(search(text)!=0){                sum++;                printf("web %d:",i);                for(int j=1;j<=n;j++){                    if(vist[j]){                        printf(" %d",j);                    }                }                printf("\n");            }        }        printf("total: %d\n",sum);    }    return 0;}
?

?

读书人网 >编程

热点推荐