病毒侵袭

分析:有点需要注意的,输入的字符是所有可见的ASCII码,刚开始没看清一直以为是小写字母.............注意到这点后这题就是裸的自动机了。
 
代码如下:
==============================================================================================
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;

const int MAXN = 1e6+7;
const int MAXM = 130;
const int oo = 1e9+37;

char webStr[MAXN], s[MAXN];
int ans[MAXN], top;///保存某个网站被那些病毒侵占了

struct node
{
    node *Fali, *next[MAXM];
    int leaf, nweb;///已经被第n个web匹配过了
};

void Insert(node *root, char s[], int num)
{
    node *p = root;

    for(int i=0; s[i]; i++)
    {
        int k = (int)s[i];

        if(p->next[k] == NULL)
            p->next[k] = new node();
        p = p->next[k];
    }

    p->leaf = num;
}
void GetFial(node *root)
{
    node *p = root, *temp;
    queue<node *> Q;

    for(int i=0; i<MAXM; i++) if(p->next[i])
    {
        p->next[i]->Fali = root;
        Q.push(p->next[i]);
    }

    while(Q.size())
    {
        p = Q.front();
        Q.pop();

        for(int i=0; i<MAXM; i++)if(p->next[i])
        {
            temp = p->Fali;

            while(temp != NULL)
            {
                if(temp->next[i] != NULL)
                {
                    p->next[i]->Fali = temp->next[i];
                    break;
                }

                temp = temp->Fali;
            }

            if(temp == NULL)
                p->next[i]->Fali = root;

            Q.push(p->next[i]);
        }
    }
}
void FreeTrie(node *root)
{
    node *p = root;

    for(int i=0; i<MAXM; i++)
    {
        if(p->next[i])
            FreeTrie(p->next[i]);
    }

    free(p);
}
void Query(node *root, int nweb)
{
    node *p = root, *temp;

    for(int i=0; webStr[i]; i++)
    {
        int k = (int)webStr[i];

        while(!p->next[k] && p!=root)
            p = p->Fali;

        if(!p->next[k])continue;

        temp = p = p->next[k];

        while(temp != root && temp->nweb != nweb)
        {
            if(temp->leaf)
                ans[top++] = temp->leaf;
            temp->nweb = nweb;
        }
    }
}

int main()
{
    int i, N, M;

    while(scanf("%d", &N) != EOF)
    {
        node *root = new node();

        for(i=1; i<=N; i++)
        {
            scanf("%s", s);
            Insert(root, s, i);
        }

        GetFial(root);
        scanf("%d", &M);

        int total = 0;

        for(i=1; i<=M; i++)
        {
            scanf("%s", webStr);

            top = 0;
            Query(root, i);

            if(top)
            {
                sort(ans, ans+top);

                printf("web %d:", i);
                for(int j=0; j<top; j++)
                    printf(" %d", ans[j]);
                printf("
");

                total += 1;
            }
        }

        printf("total: %d
", total);

        FreeTrie(root);
    }

    return 0;
}
原文地址:https://www.cnblogs.com/liuxin13/p/4750676.html