HDU 2896 病毒侵袭 (AC自动机)

题目地址:HDU 2896
AC自动机模板题。
记录每个终止节点的ID。然后在自动机里找就行了。
代码如下:

#include <iostream>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
#include <stdlib.h>
#include <map>
#include <set>
#include <stdio.h>
#include <string>
#include <time.h>
using namespace std;
#define LL long long
#define pi acos(-1.0)
#pragma comment(linker, "/STACK:1024000000")
const int mod=9901;
const int INF=0x3f3f3f3f;
const double eqs=1e-9;
const int MAXN=1000000+300;
char s[20000];
struct Trie
{
        int next[100010][130], fail[100010], id[100010], ha[600], tot[5];
        int root, L;
        int newnode()
        {
                for(int i=0;i<128;i++){
                        next[L][i]=-1;
                }
                id[L++]=0;
                return L-1;
        }
        void init()
        {
                L=0;
                root=newnode();
        }
        void Insert(char s[], int f)
        {
                int len=strlen(s);
                int now=root;
                for(int i=0;i<len;i++){
                        if(next[now][s[i]]==-1) next[now][s[i]]=newnode();
                        now=next[now][s[i]];
                }
                id[now]=f;
        }
        void Build()
        {
                queue<int>q;
                fail[root]=root;
                for(int i=0;i<128;i++){
                        int v=next[root][i];
                        if(v==-1) next[root][i]=root;
                        else {
                                fail[v]=root;
                                q.push(v);
                        }
                }
                while(!q.empty()){
                        int u=q.front();
                        q.pop();
                        for(int i=0;i<128;i++){
                                int v=next[u][i];
                                if(v==-1){
                                        next[u][i]=next[fail[u]][i];
                                }
                                else{
                                        fail[v]=next[fail[u]][i];
                                        q.push(v);
                                }
                        }
                }
        }
        int Query(char s[], int f)
        {
                memset(ha,0,sizeof(ha));
                int ans=0, now=root;
                int len=strlen(s);
                for(int i=0;i<len;i++){
                        now=next[now][s[i]];
                        int tmp=now;
                        while(tmp!=root){
                                if(id[tmp]){
                                        if(!ha[id[tmp]]){
                                                tot[ans++]=id[tmp];
                                                ha[id[tmp]]=1;
                                        }
                                }
                                tmp=fail[tmp];
                        }
                }
                if(ans){
                        printf("web %d:",f);
                        sort(tot,tot+ans);
                        for(int i=0;i<ans;i++){
                                printf(" %d",tot[i]);
                        }
                        puts("");
                }
                if(!ans) return 0;
                return 1;
        }
}ac;
int main()
{
        int n, m, i, sum;
        while(scanf("%d",&n)!=EOF){
                ac.init();
                for(i=1;i<=n;i++){
                        scanf("%s",s);
                        ac.Insert(s,i);
                }
                ac.Build();
                sum=0;
                scanf("%d",&m);
                for(i=1;i<=m;i++) {
                        scanf("%s",s);
                        sum+=ac.Query(s,i);
                }
                printf("total: %d\n",sum);
        }
        return 0;
}

你可能感兴趣的:(编程,ACM,算法与数据结构,AC自动机)