hdu 2896 病毒侵袭 ac自动机

来源:互联网 发布:php高级工程师证书 编辑:程序博客网 时间:2024/06/15 15:10

思路:裸的ac自动机,不过这题数据有点水,就算不用后缀链接也ac了


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


#include<bits/stdc++.h>using namespace std;const int maxn=100005;int n,m;char s[205],t[10005];vector<int> v;struct Ac_automata{    int val[maxn];    int ch[maxn][130];    int f[maxn],last[maxn];    int sz;    void init()    {        sz=1;        memset(val,0,sizeof(val));        memset(ch[0],0,sizeof(ch[0]));    }    int id(char c) {return c-0;}    void Insert(const char *s,int x)    {        int len=strlen(s);        int u=0;        for(int i=0;i<len;i++)        {            int c=id(s[i]);            if(!ch[u][c])            {                memset(ch[sz],0,sizeof(ch[sz]));                ch[u][c]=sz++;            }            u=ch[u][c];        }        val[u]=x;    }    void getfail()    {        queue<int> q;        for(int c=0;c<130;c++)        {            int u=ch[0][c];            if(u) {f[u]=0;q.push(u);last[u]=0;}        }        while(!q.empty())        {            int r=q.front();            q.pop();            for(int c=0;c<130;c++)            {                int u=ch[r][c];                if(!u) continue;                q.push(u);                int j=f[r];                while(j&&!ch[j][c]) j=f[j];                f[u]=ch[j][c];                last[u]=val[f[u]]?f[u]:last[f[u]];            }        }    }    void get_ans(int j)    {        if(j)        {            v.push_back(val[j]);            get_ans(last[j]);        }    }    bool Find(const char *t)    {        bool flag=false;        int len=strlen(t);        int j=0;        for(int i=0;i<len;i++)        {            int c=id(t[i]);            while(j&&!ch[j][c]) j=f[j];            j=ch[j][c];            if(val[j])            {              flag=true;              v.push_back(val[j]);              get_ans(last[j]);            }            else if(last[j])            {                flag = true;                get_ans(last[j]);            }        }        return flag;    }};Ac_automata ac;int main(){    while(~scanf("%d",&n))    {        ac.init();        for(int i=1;i<=n;i++)        {            scanf("%s",s);            ac.Insert(s,i);        }        ac.getfail();        scanf("%d",&m);        int ans=0;        for(int i=1;i<=m;i++)        {            v.clear();            scanf("%s",t);            bool flag=ac.Find(t);            if(flag)            {                ans++;                printf("web %d:",i);                sort(v.begin(),v.end());                for(int j=0;j<(int)v.size();j++)                {                    printf(" %d",v[j]);                }                printf("\n");            }        }        printf("total: %d\n",ans);    }    return 0;}


0 0
原创粉丝点击