hdu 2896 AC自动机

来源:互联网 发布:手机照片转油画软件 编辑:程序博客网 时间:2024/05/21 22:22


算是AC自动机里面的裸题吧     可恶的re了几次   看清题目        没说是由小写字母构成   , 所以next得开到127   考虑到所有的字符才行,  注意不能算重复那里我用了一个变量flash来标记每次查找是否走过   如果flash=当前编号的网站  则是走过,,其它也没啥了


#include<stdio.h>#include<string.h>#include<queue>#include<algorithm>#include<iostream>#include<malloc.h>using namespace std;struct node{    node *fail;    node *next[127];    int flash;    int cont;    int id;}*a,*b,*root;char word[20010];int num[1010],print[1100][1010];int keytree(char str[],int k){    int len=strlen(str);    node *p,*q;    p=root;    for(int i=0;i<len;i++)    {        if(p->next[str[i]-32]!=NULL)        p=p->next[str[i]-32];        else         {            q=(struct node*)malloc(sizeof(struct node));            memset(q,NULL,sizeof(struct node));            p->next[str[i]-32]=q;            p=q;        }    }        p->cont++;    p->id=k;    return 0;}int make_fail(){    queue<node*>Q;    root->fail=NULL;    a=root;    Q.push(a);    while(!Q.empty())    {        b=Q.front();        Q.pop();        for(int i=0;i<127;i++)        {            if(b->next[i]!=NULL)            {                if(b==root)                {                    b->next[i]->fail=root;                }                else                {                    a=b->fail;                    while(a!=NULL)                    {                        if(a->next[i]!=NULL)                        {                            b->next[i]->fail=a->next[i];                            break;                        }                        a=a->fail;                    }                    if(a==NULL) b->next[i]->fail=root;                }                Q.push(b->next[i]);            }        }    }    return 0;}int find(char str[],int k){    int len=strlen(str);    int sum=0;    struct node *p,*q;    p=root;    for(int i=0;i<len;i++)    {        while(p->next[str[i]-32]==NULL&&p!=root) p=p->fail;        p=p->next[str[i]-32];        if(p==NULL) p=root;        q=p;        while(q->flash!=k&&q!=root)        {            if(q->cont)            {                sum++;                num[sum]=q->id;            }            q->flash=k;            q=q->fail;        }    }    return sum;    }int main(){    int n,i,j;    char str[500];    scanf("%d",&n);    getchar();    root=(struct node*)malloc(sizeof(struct node));    memset(root,NULL,sizeof(struct node));    for(i=1;i<=n;i++)    {        gets(str);        keytree(str,i);    }    make_fail();    int m;    int x=0;    int t;    int number[1100];    scanf("%d",&m);    getchar();    for(i=1;i<=m;i++)    {        gets(word);        t=find(word,i);        if(t)        {            sort(num+1,num+1+t);            x++;            number[x]=i;            print[x][0]=t;            for(j=1;j<=t;j++)            print[x][j]=num[j];        }    }    for(i=1;i<=x;i++)    {        printf("web %d:",number[i]);        for(j=1;j<=print[i][0];j++)        printf(" %d",print[i][j]);        printf("\n");    }    printf("total: %d\n",x);    return 0;}

0 0