hdu 3065 病毒侵袭持续中

http://acm.hdu.edu.cn/showproblem.php?pid=3065

AC自动机

代码:

#include<iostream>

#include<cmath>

#include<cstdio>

#include<string>

#include<cstring>

#include<vector>

#include<stack>

#include<queue>

#include<set>

#include<map>

#include<algorithm>



#define LL long long



using namespace std;



const int INF=0x3f3f3f3f;

const int N=1005;

const int M=505;

const int K=26;

struct nodeTrie

{

    nodeTrie()

    {

        v=0;

        fail=NULL;

        for(int i=0;i<K;++i)

        next[i]=NULL;

    }

    int v;

    nodeTrie *fail;

    nodeTrie *next[K];

}*root;

char s[N][55];

char web[2000005];

int num[N];

void addWord(nodeTrie *p,char *s,int k)

{

    if(s[0]=='\0') return ;

    for(int i=0;s[i]!='\0';++i)

    {

        if(p->next[s[i]-'A']==NULL)

        p->next[s[i]-'A']=new nodeTrie;

        p=p->next[s[i]-'A'];

    }

    (p->v)=k;

}

void init(int n)

{

    root=new nodeTrie;

    for(int i=1;i<=n;++i)

    {

        gets(s[i]);

        addWord(root,s[i],i);

    }

}

void bfs(nodeTrie *p)

{

    p->fail=root;

    queue<nodeTrie *>qt;

    qt.push(p);

    while(!qt.empty())

    {

        nodeTrie *y;

        nodeTrie *x=qt.front();qt.pop();

        for(int i=0;i<K;++i)

        if(x->next[i]!=NULL)

        {

            qt.push(x->next[i]);

            if(x==root)

            {x->next[i]->fail=root;continue;}

            y=x->fail;

            while(y!=root&&y->next[i]==NULL)

            y=y->fail;

            if(y->next[i]!=NULL)

            x->next[i]->fail=y->next[i];

            else

            x->next[i]->fail=root;

        }

    }

}

int match(nodeTrie *p,char *s)

{

    int wordCount=0;

    int l=0;

    while(s[l]!='\0')

    {

        if(s[l]<'A'||s[l]>'Z') {p=root;++l;continue;}

        while(p->next[s[l]-'A']==NULL&&p!=root)

        p=p->fail;

        if(p->next[s[l]-'A']!=NULL)

        p=p->next[s[l]-'A'];

        ++l;

        nodeTrie *fp=p;

        while(fp!=root)

        {

            if((fp->v)>0)

            ++num[fp->v];

            fp=fp->fail;

        }

    }

    return wordCount;

}

int main()

{

    //freopen("data.in","r",stdin);

    int n;

    while(scanf("%d ",&n)!=EOF)

    {

        init(n);

        bfs(root);

        gets(web);

        memset(num,0,sizeof(num));

        match(root,web);

        for(int i=1;i<=n;++i)

        if(num[i]>0)

        printf("%s: %d\n",s[i],num[i]);

    }

    return 0;

}

  

你可能感兴趣的:(HDU)