【HDU-2222】Keywords Search(AC自动机模板)
2014-10-16 16:44
603 查看
AC自动机的模板题,自己手敲了一遍模板。
添加失配边的时候,对每个结点的26条字母边链接的子结点扫一遍,如果结点存在,那么这个子结点的失配边就是主结点失配边对应结点链接的子节点。
如果结点不存在,那么这个结点就直接连到主结点失配边对应结点链接的子节点。
感觉AC自动机好难懂啊。。。QAQ
添加失配边的时候,对每个结点的26条字母边链接的子结点扫一遍,如果结点存在,那么这个子结点的失配边就是主结点失配边对应结点链接的子节点。
如果结点不存在,那么这个结点就直接连到主结点失配边对应结点链接的子节点。
感觉AC自动机好难懂啊。。。QAQ
11885512 | 2014-10-16 16:22:43 | Accepted | 2222 | 687MS | 26688K | 2772 B | G++ | KinderRiven |
#include<stack> #include<queue> #include<map> #include<set> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn = 555555; const int maxn_sign = 26; const int maxd = 1111111; int root; struct Trie{ //AC自动机 int tr[maxn][maxn_sign];//Trie树 int fail[maxn]; //失配边 int val[maxn]; int sz; //总结点数 int counts; int index(int c){ if(c >= 'a' && c <= 'z') return c - 'a'; if(c >= 'A' && c <= 'Z') return c - 'A'; } void init(){ //树的初始化 sz = 0; val[0] = 0; counts = 0; for(int i = 0; i < 26; i++) tr[0][i] = -1; } int newnode(){ //申请新的结点 val[sz] = 0; for(int i = 0; i < 26; i++) tr[sz][i] = -1; sz ++; return sz - 1; } void insert(char *str){ int u = 0,n = strlen(str); for(int i = 0; i < n; i++){ int e = index(str[i]); if(tr[u][e] == -1){ //没有这个结点 int d = newnode(); tr[u][e] = d; } u = tr[u][e]; } val[u] ++; } void buildfail(){ queue<int>q; fail[root] = root; //根结点的失配边连向自己 for(int i = 0; i < 26; i++){ if(tr[root][i] == -1) tr[root][i] = root; else{ q.push(tr[root][i]); fail[tr[root][i]] = root; } } while(!q.empty()){ int node = q.front(); q.pop(); for(int i = 0; i < 26; i++){ if(tr[node][i] == -1){ tr[node][i] = tr[fail[node]][i]; } else{ fail[tr[node][i]] = tr[fail[node]][i]; q.push(tr[node][i]); } } } } void triecount(char *str){ int L = strlen(str); int u = 0; for(int i = 0; i < L;i ++){ u = tr[u][index(str[i])]; int temp = u; while(temp != root){ counts += val[temp]; val[temp] = 0; temp = fail[temp]; } } } }; Trie ac; char s[maxd]; int main(){ int T; scanf("%d",&T); while(T--){ ac.init(); int n; root = ac.newnode(); char str[55]; scanf("%d",&n); for(int i = 0; i < n; i++){ scanf("%s",str); ac.insert(str); } scanf("%s",s); ac.buildfail(); ac.triecount(s); printf("%d\n",ac.counts); //printf("%d\n",ac.sz); } return 0; }
相关文章推荐
- HDU 2222 Keywords Search (AC自动机模板)
- HDU 2222 Keywords Search 【AC自动机模板】
- hdu 2222 Keywords Search(AC自动机模板)
- HDU 2222 Keywords Search(AC自动机 模板)
- Keywords Search - HDU 2222(AC自动机模板)
- 文章标题 HDU 2222 : Keywords Search (AC自动机模板)
- hdu 2222 Keywords Search(AC自动机模板)
- hdu 2222:Keywords Search(AC自动机模板)
- HDU_2222 Keywords Search 【AC自动机模板题】【动态链表】
- hdu -2222 Keywords Search(AC自动机模板)
- CUGB专题训练之数据结构:E - Keywords Search(HDU 2222 AC自动机经典入门模板题)
- HDU 2222 Keywords Search 【AC自动机(模板题)】
- HDU 2222 Keywords Search(AC自动机模板)
- HDU 2222 Keywords Search(AC自动机模板)
- 【模板练习——AC自动机】Keywords Search HDU - 2222
- AC自动机学习小记 Hdu 2222 Keywords Search (模板)
- HDU 2222 Keywords Search 【AC自动机模板】
- [AC自动机模板题] HDU 2222 Keywords Search
- HDU-2222 Keywords Search(AC自动机--模板题)
- Match:Keywords Search(AC自动机模板)(HDU 2222)