[HDU 2896] 病毒侵袭 AC自动机

http://acm.hdu.edu.cn/showproblem.php?pid=2896

题意:中文题看得懂

思路:AC自动机。。。。。。。数据也被改了不能动态分配,开数组咯

#include 
#include 
#include 
#include 

using namespace std;/

struct node{
    int counts;
    int fail;
    int next[128];
    static int newnode;
    node(){
        counts = 0;
        for(int i = 0; i < 128; i++){
            next[i] = 0;
        }
        fail = 0;
    }
};

bool vis[520];
node tr[58020];
char str[10010];
queue<int>que;
int node::newnode = 1;

int Build(int rt, char *str, int id) //字典树
{
    int i = -1;
    int pr = rt;
    while(str[++i]){
        int pos = str[i];
        if(!tr[pr].next[pos]){
            tr[pr].next[pos] = node::newnode++;
        }
        pr = tr[pr].next[pos];
    }
    tr[pr].counts = id;
    return rt;
}

void Automaton(int rt) //BFS构造fail指针
{
    que.push(rt);
    while(!que.empty()){
        int pr = que.front();
        que.pop();
        for(int i = 0; i < 128; i++){
            int son = tr[pr].next[i];
            if(son == NULL)
                continue;
            if(pr == rt){
                tr[son].fail = pr;
            }
            else{
                int temp = tr[pr].fail;
                while(temp){
                    if(tr[temp].next[i]){
                        tr[son].fail = tr[temp].next[i];
                        break;
                    }
                    temp = tr[temp].fail;
                }
                if(temp == NULL)
                    tr[son].fail = rt;
            }
            que.push(son);
        }
    }
}

int query(int rt, char *str) //询问
{
    int pr = rt;
    int i = -1, sum = 0;
    while(str[++i]){
        int pos = str[i];
        while(!tr[pr].next[pos] && pr != rt){
            pr = tr[pr].fail;
        }
        pr = (tr[pr].next[pos] == NULL) ? rt : tr[pr].next[pos];
        int temp = pr;
        while(temp != rt){
            if(!vis[tr[temp].counts] && tr[temp].counts){
                sum++;
                vis[tr[temp].counts] = true; //标记
            }
            temp = tr[temp].fail;
        }
    }
    return sum;
}

int main()
{
    int n, m;
    while(~scanf("%d", &n)){
        node::newnode = 1;
        int rt = node::newnode++;
        for(int i = 1; i <= n; i++){
            scanf("%s", str);
            rt = Build(rt, str, i);
        }
        Bfs(rt);
        scanf("%d", &m);
        int sum = 0;
        for(int i = 1; i <= m; i++){
            scanf("%s", str);
            memset(vis, false, sizeof(vis));
            if(query(rt, str)){
                printf("web %d:", i);
                for(int k = 1; k <= n; k++){
                    if(vis[k])
                        printf(" %d", k);
                }
                printf("\n");
                sum++;
            }
        }
        printf("total: %d\n",sum);
    }
    return 0;
}

你可能感兴趣的:(字符串)