HDU 2896 AC自动机

来源:互联网 发布:Java建立图书类 编辑:程序博客网 时间:2024/05/18 10:52

题目描述是中文的。。

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

样例太有迷惑性了。  没想到它存储的是128个字符信息。这跟平时所经常碰到的不太一样。。

还是题目没读清楚啊。。  然后又因为ASCII码是从 32开始时网站中会出现的。。所以从31开始计数。

http://www.cnblogs.com/songsu/articles/1454333.html  ASCII 表


第二次做AC自动机的题目了。。路漫漫兮

#include <cstdio>#include <cstdlib>#include <iostream>#include <cstring>#include <vector>#include <memory.h>#include <algorithm>using namespace std;const int N = 500000;struct node{node *fail;node *next[130];int id;void clear(){fail=NULL;id = -1;memset(next,0,sizeof(next));}}stack[N], *root,*cur,*q[N];int head,tail;bool vis[11111];char virus[11111],website[111111];vector<int> ret;void insert(char s[],int id){node* p =root;int n = strlen(s),o;for(int i = 0;i < n;i++){o = s[i]-31;if(p->next[o]==NULL){p->next[o]=++cur;cur->clear();}p=p->next[o];}p->id = id;}void do_AC(){node *p,*tmp;head = tail = 0;q[tail++]=root;while(head!=tail){p = q[head++];for(int i = 0;i <= 128;i++){if(p->next[i] != NULL){q[tail++]=p->next[i];if(p == root){p->next[i]->fail = root;}else{tmp = p->fail;while(tmp != NULL){if(tmp->next[i]!=NULL){p->next[i]->fail=tmp->next[i];break;}tmp = tmp->fail;}if(tmp == NULL){p->next[i]->fail=root;}}}}}}void query(char s[]){node *p=root,*tmp;int n = strlen(s),o;ret.clear();for(int i=0;i < n;i++){o = s[i]-31;while(p->next[o]==NULL && p != root)p = p->fail;p = p->next[o];if(p == NULL)p = root;tmp = p;while(tmp != root && tmp->id!=-1){if(!vis[tmp->id]){vis[tmp->id]=true;ret.push_back(tmp->id);}tmp=tmp->fail;}}}int main(){int n,m;while(scanf("%d",&n)!=EOF){root = cur = stack;cur->clear();for(int i = 1;i <= n;i++){scanf("%s",virus);insert(virus,i);}scanf("%d",&m);do_AC();int total=0;for(int i = 1;i <= m;i++){scanf("%s",website);memset(vis,0,sizeof(vis));query(website);if(ret.size() != 0){total++;sort(ret.begin(),ret.end());printf("web %d:",i);for(int j = 0;j < ret.size();j++)printf(" %d",ret[j]);printf("\n");}}printf("total: %d\n",total);}return 0;}


0 0
原创粉丝点击