hdu 2896

来源:互联网 发布:splice视频编辑软件 编辑:程序博客网 时间:2024/04/30 08:39

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


AC自动机。。建好AC自动机,然后只需要开个数组ans[]保存每个网站所含病毒的id,初始全为false.


#include<cstdio>#include<cstring>using namespace std;char str[11000];int total,head,tail;struct node{    node *next[130];    node *fail;    int cnt,id;    node(){        fail=NULL;  cnt=0;  memset(next,NULL,sizeof(next));    }} *q[500000];void insert(node *root,int id){    node *p=root;  int i=0,index;    while(str[i]){        index=str[i]-31;        if(p->next[index]==NULL)  p->next[index]=new node();        p=p->next[index];        i++;    }    p->cnt++;  p->id=id;}void build_ac(node *root){    root->fail=NULL;    q[head++]=root;    node *p=NULL;    while(head!=tail){        node *temp = q[tail++];        for(int i=0;i<=128;i++){            if(temp->next[i]!=NULL){               if(temp==root)  temp->next[i]->fail=root;               else{                    p=temp->fail;                    while(p!=NULL){                         if(p->next[i]!=NULL){                            temp->next[i]->fail=p->next[i];                            break;                         }                         p=p->fail;                    }                    if(p==NULL)  temp->next[i]->fail=root;               }               q[head++]=temp->next[i];            }        }    }}bool ans[1000];int cnt;int query(node *root){    int i=0,index;   node *p = root;    while(str[i]){        index=str[i]-31;        while(p->next[index]==NULL&&p!=root)  p=p->fail;        p=p->next[index];        p=(p==NULL)?root:p;        node *temp = p;        while(temp!=root&&temp->cnt>0){            if(ans [ temp->id]==false)  cnt++,ans[ temp->id ]=true;            temp=temp->fail;        }        i++;    }}int main(){    int n,m;    total=0;    while(scanf("%d",&n)!=EOF){        node *root=new node();        head=tail=0; total=0;        for(int i=0;i<n;i++)  scanf("%s",str),insert(root,i+1);        scanf("%d",&m);        build_ac(root);        for(int i=1;i<=m;i++){            memset(ans,false,sizeof(ans));  cnt=0;            scanf("%s",str);            query(root);            if(cnt>0){ printf("web %d:",i);            for(int j=1;j<=500;j++) if(ans[j]==true)             printf(" %d",j);            printf("\n");            total++;            }        }        printf("total: %d\n",total);       // while(1);    }    return 0;}


原创粉丝点击