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自动机模板)
原文:http://blog.csdn.net/u013451221/article/details/40150365