hdu 2896 病毒侵袭(AC自动机水题)

来源:互联网 发布:园林设计软件图库 编辑:程序博客网 时间:2024/06/06 01:46

考查知识点:AC自动机

注意:每个网站的“源码字符串长度在7000—10000之间”。
我开了一个字符串char c [300],提交结果不会报字符串溢出,而是wrong answer
所以别吝惜这点小内存。

#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <set>#include <algorithm>using namespace std;#define mem(a,b) memset(a,b,sizeof(a))#define INF 1<<30#define M 502#define kind 130//ascII个数struct node{  int  isword;  node *fail;  node * next[kind];  node()  {      isword=0;      fail=NULL;      mem(next,0);  }}*root;set<int> web;void Insert(node *p,char s[],int x){    int index,i=0;    while(s[i])    {        index=(int)s[i];        if(p->next[index]==NULL)          p->next[index]=new node;        p=p->next[index];        i++;    }    p->isword=x;}void build_ac_automation(node *p){    queue<node*>Q;    Q.push(p);    node *temp;    while(!Q.empty())    {        temp=Q.front();Q.pop();        p=NULL;        for(int i=0; i<kind; i++)         if(temp->next[i]!=NULL)         {             if(temp==root)temp->next[i]->fail=root;             else             {                 p=temp->fail;//p向着temp的失败指针向上走                 while(p!=NULL)                 {                     if(p->next[i]!=NULL)                     {                         temp->next[i]->fail=p->next[i];                         break;                     }                     p=p->fail;//p向着自己的失败指针向上走                 }                 if(p==NULL)temp->next[i]->fail=root;             }             Q.push(temp->next[i]);         }    }}void query(node *p,char s[]){    int i=0,index;    while(s[i])    {        index=(int)s[i];        while(p->next[index]==NULL && p!=root)p=p->fail;        p=p->next[index];        if(p==NULL)p=root;        node *temp=p;        while(temp!=root)        {           if(temp->isword)            web.insert(temp->isword);            //cout<<temp->isword;           temp=temp->fail;        }        i++;    }}void myfree(node *p){    for(int i=0;i<kind;i++)     if(p->next[i]!=NULL)        myfree(p->next[i]);     delete p;}int main(){    int m,n,i,j,total;    char s[202];    char virus[10002];//"源码字符串长度在7000—10000之间。"我直接用s[]这里错了3次    while(~scanf("%d",&m))    {        root=new node;        total=0;        for(i=1;i<=m;i++)        {            scanf("%s",s);            Insert(root,s,i);        }        build_ac_automation(root);        scanf("%d",&n);        for(i=1;i<=n;i++)        {            scanf("%s",virus);            web.clear();            query(root,virus);            if(web.size()>0)            {                total++;                printf("web %d:",i);                set<int>::iterator it;                for(it=web.begin();it!=web.end();it++)                    printf(" %d",*it);                printf("\n");            }        }        printf("total: %d\n",total);        myfree(root);    }    return 0;}


原创粉丝点击