HDU 2896 病毒侵袭 【AC自动机】

来源:互联网 发布:大数据开源项目 编辑:程序博客网 时间:2024/05/22 11:29

HDU 2222 仅仅求出了和文本串匹配的模式串个数,本题要求求出匹配的模式串的编号。

不同的部分在代码中的注释部分。

#include <cstdio>#include <queue>#include <algorithm>#include <vector>#include <iostream>#include <cstring>using namespace std;vector<int> ans;struct AC_Automata {    #define N 60005    #define M 130    int ch[N][M], sz;    int val[N], last[N], f[N];    void clear() { sz = 1; memset(ch[0], 0, sizeof(ch[0])); }    int idx(char c) { return c; }    void insert(char s[], int v) {        int u = 0;        for (int i=0; s[i]; i++) {            int c = idx(s[i]);            if (!ch[u][c]) {                memset(ch[sz], 0, sizeof(ch[sz]));                val[sz] = 0;                ch[u][c] = sz++;            }            u = ch[u][c];        }        val[u] = v;    }    void build() {        queue<int> q;        f[0] = 0;        for (int c=0; c<M; c++) {            int u = ch[0][c];            if (u) { f[u] = 0, q.push(u); last[u] = 0; }        }        while (!q.empty()) {            int r = q.front(); q.pop();            for (int c=0; c<M; c++) {                int u = ch[r][c];                if (!u) { ch[r][c] = ch[f[r]][c]; continue; }                q.push(u);                f[u] = ch[f[r]][c];                last[u] = val[f[u]] ? f[u] : last[f[u]];            }        }    }    void find(char *s) {        int j = 0;        for (int i=0; s[i]; i++) {            int c = idx(s[i]);            j = ch[j][c];            if (val[j]) print(j);            else if (last[j]) print(last[j]);        }    }    void print(int j) { //打印以结点j结尾的所有字符串        if (j) {            //printf("%d: %d\n", j, val[j]);            ans.push_back(val[j]);            print(last[j]);        }    }} ac;char s[210], t[10010];int main() {#ifndef ONLINE_JUDGE    freopen("in.txt", "r", stdin);#endif    int n, m;    while (scanf("%d", &n) == 1) {        ac.clear();        for (int i=1; i<=n; i++) {            scanf(" %s", s); ac.insert(s, i);        }        ac.build();        scanf(" %d", &m);        int tot = 0;        for (int j=1; j<=m; j++) {            ans.clear();            scanf(" %s", t);            ac.find(t);            if (ans.size() == 0) continue;            sort(ans.begin(), ans.end());            int k = unique(ans.begin(), ans.end()) - ans.begin();            printf("web %d:", j);            for (int i=0; i<k; i++) printf(" %d", ans[i]); puts("");            tot++;        }        printf("total: %d\n", tot);    }    return 0;}



原创粉丝点击