首页 > 代码库 > hdu 2896 AC自动机
hdu 2896 AC自动机
算是AC自动机里面的裸题吧 可恶的re了几次 看清题目 没说是由小写字母构成 , 所以next得开到127 考虑到所有的字符才行, 注意不能算重复那里我用了一个变量flash来标记每次查找是否走过 如果flash=当前编号的网站 则是走过,,其它也没啥了
#include<stdio.h> #include<string.h> #include<queue> #include<algorithm> #include<iostream> #include<malloc.h> using namespace std; struct node { node *fail; node *next[127]; int flash; int cont; int id; }*a,*b,*root; char word[20010]; int num[1010],print[1100][1010]; int keytree(char str[],int k) { int len=strlen(str); node *p,*q; p=root; for(int i=0;i<len;i++) { if(p->next[str[i]-32]!=NULL) p=p->next[str[i]-32]; else { q=(struct node*)malloc(sizeof(struct node)); memset(q,NULL,sizeof(struct node)); p->next[str[i]-32]=q; p=q; } } p->cont++; p->id=k; return 0; } int make_fail() { queue<node*>Q; root->fail=NULL; a=root; Q.push(a); while(!Q.empty()) { b=Q.front(); Q.pop(); for(int i=0;i<127;i++) { if(b->next[i]!=NULL) { if(b==root) { b->next[i]->fail=root; } else { a=b->fail; while(a!=NULL) { if(a->next[i]!=NULL) { b->next[i]->fail=a->next[i]; break; } a=a->fail; } if(a==NULL) b->next[i]->fail=root; } Q.push(b->next[i]); } } } return 0; } int find(char str[],int k) { int len=strlen(str); int sum=0; struct node *p,*q; p=root; for(int i=0;i<len;i++) { while(p->next[str[i]-32]==NULL&&p!=root) p=p->fail; p=p->next[str[i]-32]; if(p==NULL) p=root; q=p; while(q->flash!=k&&q!=root) { if(q->cont) { sum++; num[sum]=q->id; } q->flash=k; q=q->fail; } } return sum; } int main() { int n,i,j; char str[500]; scanf("%d",&n); getchar(); root=(struct node*)malloc(sizeof(struct node)); memset(root,NULL,sizeof(struct node)); for(i=1;i<=n;i++) { gets(str); keytree(str,i); } make_fail(); int m; int x=0; int t; int number[1100]; scanf("%d",&m); getchar(); for(i=1;i<=m;i++) { gets(word); t=find(word,i); if(t) { sort(num+1,num+1+t); x++; number[x]=i; print[x][0]=t; for(j=1;j<=t;j++) print[x][j]=num[j]; } } for(i=1;i<=x;i++) { printf("web %d:",number[i]); for(j=1;j<=print[i][0];j++) printf(" %d",print[i][j]); printf("\n"); } printf("total: %d\n",x); return 0; }
hdu 2896 AC自动机
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。