HDU2896 病毒侵袭

42 篇文章 0 订阅
6 篇文章 0 订阅

题目传送门

AC自动机第一题~

一看就是一个非常简单的多串匹配问题了,输出方案?记录一下就好了

注意这里code是Trie图,它是AC自动机的改进版本,有效利用了原本无用的边,这反而简化了代码

#include<queue>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 100010
using namespace std;
char s[N];
int fail[N],son[N][128],c[N],cnt=1,n,T=0;
inline void insert(char* s,int pos){
    int x=1;
    for(;*s;++s)
        x=son[x][*s]?son[x][*s]:son[x][*s]=++cnt;
    c[x]=pos;
}
inline void build(){
    queue<int> q;
    for(int i=0;i<128;++i)
        if(!son[1][i]) son[1][i]=1;
        else q.push(son[1][i]),fail[son[1][i]]=1;
    for(int x;!q.empty();q.pop()){
        x=q.front();
        for(int i=0;i<128;++i)
            if(!son[x][i]) son[x][i]=son[fail[x]][i];
        else q.push(son[x][i]),fail[son[x][i]]=son[fail[x]][i];
    }
}
inline bool query(char* s){
    bool vis[510]={0},v=0;
    for(int x=1;*s;++s){
        x=son[x][*s];
        for(int j=x;j!=1;j=fail[j])
            if(c[j]) vis[c[j]]=v=1;
    }
    if(!v) return 0;
    printf("web %d:",T);
    for(int i=1;i<=n;++i) 
        if(vis[i]) printf(" %d",i);
    puts(""); return 1;
}
int __18520(){
    if(scanf("%d",&n)<0) return 0; 
    for(int i=1;i<=n;++i){
        scanf("%s",s); insert(s,i);
    }
    build(); int ans=0,m; scanf("%d",&m); 
    for(T=1;T<=m;++T){
        scanf("%s",s); ans+=query(s);
    }
    printf("total: %d\n",ans); return cnt=1;
}
int main(){ while(__18520()); }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值