zoukankan      html  css  js  c++  java
  • hdu 2896 病毒侵袭 夜

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

    AC自动机

    ASCII可见字符是从 33~126

    代码:

    #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=10005;
    const int M=505;
    const int K=128;
    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];
    bool had[M];
    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]]==NULL)
            p->next[s[i]]=new nodeTrie;
            p=p->next[s[i]];
        }
        (p->v)=k;
    }
    void init(int n)
    {
        root=new nodeTrie;
        for(int i=1;i<=n;++i)
        {
            gets(s);
            addWord(root,s,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')
        {
            while(p->next[s[l]]==NULL&&p!=root)
            p=p->fail;
            if(p->next[s[l]]!=NULL)
            p=p->next[s[l]];
            ++l;
            nodeTrie *fp=p;
            while(fp!=root)
            {
                if((fp->v)>0)
                {
                    if(had[fp->v]==false)
                    {++wordCount;had[fp->v]=true;}
                }
                fp=fp->fail;
            }
        }
        return wordCount;
    }
    void trieClear(nodeTrie *p)
    {
        queue<nodeTrie *>qt;
        qt.push(p);
        while(!qt.empty())
        {
            nodeTrie *x=qt.front();qt.pop();
            for(int i=0;i<K;++i)
            if(x->next[i]!=NULL)
            qt.push(x->next[i]);
            delete x;
        }
    }
    int main()
    {
        //freopen("data.in","r",stdin);
        int n;
        while(scanf("%d ",&n)!=EOF)
        {
            init(n);
            bfs(root);
            int m;
            scanf("%d ",&m);
            int total=0;
            for(int i=1;i<=m;++i)
            {
                gets(s);
                int k;
                memset(had,false,sizeof(had));
                k=match(root,s);
                if(k>0)
                {
                    ++total;
                    printf("web %d:",i);
                    for(int j=1;j<=n;++j)
                    if(had[j])
                    printf(" %d",j);
                    printf("\n");
                }
            }
            printf("total: %d\n",total);
            //trieClear(root);
        }
        return 0;
    }
    

      

  • 相关阅读:
    python的浅拷贝和深拷贝的区别
    listview中添加CheckBox的完美实现
    Content Provider 详解
    listView 结合 ArrayList和HashMap 的应用
    App Widget Provider 应用
    Android学习:SeekBar实现音量调节
    android MenuInflater 用XML文件布局
    android 创建菜单的心得
    Android 文件操作
    Android ImageView 总结【转载】
  • 原文地址:https://www.cnblogs.com/liulangye/p/2975921.html
Copyright © 2011-2022 走看看