HDOJ 2896 病毒侵袭(AC自动机入门)

题意:

求感染病毒的网站,并输出其感染的病毒特征码编号。

思路:

AC自动机入门,思路同 HDOJ 2222

 

#include <iostream> #include <deque> #include <algorithm> using namespace std; const int MAX_NODE = 500 * 200 + 10; const int CHILD_NUM = 128; class AcAutomaton { private: int size; int trie[MAX_NODE][CHILD_NUM]; int fail[MAX_NODE]; int value[MAX_NODE]; int table[CHILD_NUM]; bool visit[MAX_NODE]; public: void Initialize() {

        fail[0] = 0; for (int i = 0; i < CHILD_NUM; ++i)

            table[i] = i; } void Reset() {

        size = 1;

        memset(trie[0], 0, sizeof(trie[0]));

        memset(value, 0, sizeof(value)); } void Insert(char* word, int key) { int p = 0; for (int i = 0; word[i]; ++i) { int m = table[word[i]]; if (!trie[p][m]) {

                memset(trie[size], 0, sizeof(trie[0]));

                trie[p][m] = size++; }

            p = trie[p][m]; }

        value[p] = key; } void Construct() {

        deque<int> que; for (int i = 0; i < CHILD_NUM; ++i) if (trie[0][i]) {

                fail[trie[0][i]] = 0;

                que.push_back(trie[0][i]); } while (!que.empty()) { int u = que.front();

            que.pop_front(); for (int i = 0; i < CHILD_NUM; ++i) { int& v = trie[u][i]; if (v) {

                    que.push_back(v);

                    fail[v] = trie[fail[u]][i]; } else

                    v = trie[fail[u]][i]; } } } int Work(char* word, int arr[]) {

        memset(visit, false, sizeof(visit)); int num = 0, p = 0; for (int i = 0; word[i]; ++i) { int m = table[word[i]]; int t = p = trie[p][m]; while (value[t] && !visit[t]) {

                arr[num++] = value[t];

                visit[t] = true;

                t = fail[t]; if (num >= 3) return num; } } return num; } };



AcAutomaton Ac; char word[10010]; int main() { int n;

    scanf("%d", &n);



    Ac.Initialize();

    Ac.Reset(); char is[210]; for (int i = 1; i <= n; ++i) {

        scanf("%s", is);

        Ac.Insert(is, i); }

    Ac.Construct();



    scanf("%d", &n); int count = 0; for (int i = 1; i <= n; ++i) { int arr[12], num = 0;



        scanf("%s", word);

        num = Ac.Work(word, arr); if (num) {

            sort(arr, arr + num);

            printf("web %d:", i); for (int j = 0; j < num; ++j)

                printf(" %d", arr[j]);

            printf("\n"); ++count; } }

    printf("total: %d\n", count); return 0; }

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