首页 > 代码库 > 【HDU-2222】Keywords Search(AC自动机模板)
【HDU-2222】Keywords Search(AC自动机模板)
AC自动机的模板题,自己手敲了一遍模板。
添加失配边的时候,对每个结点的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自动机模板)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。