hdu2896(ac自动机)

链接:点击打开链接

题意:给出N个病毒的字符串,再给出M个网站的字符串,求字符串中含有病毒的数量和一共含有病毒的网址,具体看样例

代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <queue>
using namespace std;
int str[100005][128],dis[100005];
int fail[100005],vis[100005];
int root,id;
void insert(char *s){
    int u=0;
    for(;*s;s++){
        if(!str[u][*s-' '])
        str[u][*s-' ']=root++;
        u=str[u][*s-' '];
    }
    dis[u]=id++;
}
void getfail(){
    int u,v,i,temp;
    queue<int>q;
    while(!q.empty())q.pop();
    q.push(0);
    while(q.size()){
       u=q.front();q.pop();
       for(i=0;i<128;i++)
       if(v=str[u][i]){
            if(u==0)
            fail[v]=0;
            else{
                temp=fail[u];
                while(temp&&!str[temp][i])
                temp=fail[temp];
                fail[v]=str[temp][i];
            }
            q.push(v);
       }
    }
}
int acauto(char *s){
    int temp,star,sign;
    temp=sign=0;
    for(;*s;s++){
    while(temp&&!str[temp][*s-' '])
    temp=fail[temp];
    star=temp=str[temp][*s-' '];
    while(star&&!vis[star]&&dis[star]){
        vis[star]=1;
        star=fail[star];
        sign=1;
    }
    }
    if(sign)
    return 1;
    return 0;
}                                               //这题就是AC自动机模板,唯一不同就是用一个vis数组记录
int main(){                                     //AC自动机模板和解析详见http://blog.csdn.net/stay_accept/article/details/47613961
    int n,m,i,j,sum,flag;
    char s[250],str[10005];
    memset(str,0,sizeof(str));
    memset(fail,0,sizeof(fail));
    memset(dis,0,sizeof(dis));
    root=id=1;sum=0;
    scanf("%d",&n);
    for(i=0;i<n;i++){
        scanf("%s",s);
        insert(s);
    }
    getfail();
    scanf("%d",&m);
    for(i=1;i<=m;i++){
        scanf("%s",str);
        memset(vis,0,sizeof(vis));
        if(acauto(str)){
            printf("web %d:",i);
            sum++;
            for(j=0;j<root;j++){
                flag=0;
                if(vis[j]){
                    printf(" %d",dis[j]);
                    flag++;
                }
                if(flag==3)
                break;
            }
            printf("\n");
        }
    }
    printf("total: %d\n",sum);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值