hdu2896 AC自动机

ac自动机题目 , 和hdu2222差不多,不过这里的字符包含ASCII所有可见字符,所以在建立trie树是需要将数组开大,否则就会访问越界,又是纠结好久,又看了一遍题目才发现。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>

using namespace std;

#define MAXN 100
#define MAXX 100100
int sum ;
char arr[MAXX];
int flag[505];

struct node
{
    int num;
    char str;
    node *fail;
    node *next[MAXN];
    node()
    {
        num = 0;
        fail = NULL;
        for(int i = 0 ; i < MAXN ; i ++ )
            next[i] = NULL ;
    }
};

void Insert(node *root,char a[], int k)
{
    node *current , *newnode;
    int len = strlen(a);
    current = root ;
    for(int i = 0 ; i < len ; i ++ )
    {
        int m = a[i] - ' ';
        if(current -> next[m] != NULL)
        {
            current = current -> next[m];
            if(i == len - 1) (current -> num) = k ;
        }
        else
        {
            newnode = new node();
            newnode -> str = a[i];
            current -> next[m] = newnode;
            current = newnode;
            if(i == len - 1) (current -> num) = k;
        }
    }
}

void BuildFail(node *root)
{

    queue <node*>Q;
    root -> fail = root;
    for(int i = 0 ; i < MAXN ; i ++ )
    {
        if(root -> next[i] == NULL)
        {
             root -> next[i]  = root ;
        }
        else
        {
            root -> next[i] -> fail = root ;
            Q.push(root -> next[i]);
        }

    }
    while(!Q.empty())
    {
        node *current ;
        current = Q.front();
        Q.pop();
        for(int i = 0 ; i < MAXN ; i ++ )
        {
            if(current -> next[i] == NULL)
                current -> next[i]  = current -> fail -> next[i];
            else
            {
           //     cout << current -> next[i] ->str << endl ;
                current -> next[i] -> fail = current -> fail -> next[i];
                Q.push(current -> next[i]);
            }
        }
    }
}

void Query(node *root,char a[])
{
    node *current , *newnode;
    int len = strlen(a);
    current = root;
    for(int i = 0 ; i < len ; i ++ )
    {
        int m = a[i] - ' ';
        while(current -> next[m] == NULL && current != root) current = current -> fail;
        current = current -> next[m];
        newnode = current ;
        while(newnode != root)
        {
            if(1 <= newnode -> num&& newnode -> num < 505) flag[newnode -> num] = 1 ;
            newnode = newnode -> fail ;
        }
    }
}

int main()
{
    int n;
    while( scanf("%d" , &n) != EOF)
    {
        node *root = new node();
        getchar();
        char a[205];
        for(int i = 0 ; i < n ; i ++ )
        {
            gets(a);
            Insert(root,a,i + 1);
        }
        scanf("%d" , &n) ;
        getchar();
        sum = 0;
        BuildFail(root);
        for(int i = 0 ; i < n ; i ++ )
        {
            memset(flag , 0 , sizeof(flag));
            gets(arr);
            Query(root,arr);
            int j;
            for( j = 1 ; j < 504 ; j ++ )
            {
                if(flag[j]) break;
            }
            if(j < 504)
            {
                sum ++ ;
                printf("web %d:" , i + 1);
                for(int j = 1 ; j < 504 ; j ++ )
                {
                    if(flag[j]) printf(" %d",j);
                }
                printf("\n");
            }
        }
        printf("total: %d\n" , sum);
    }
}


你可能感兴趣的:(hdu2896 AC自动机)