hdu 2896 病毒侵袭 AC自动机

来源:互联网 发布:雷尼绍测头编程 编辑:程序博客网 时间:2024/05/22 13:07

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

题意:给你N个匹配串和M个模式串, 问你每个模式串中,N个匹配串有哪些出现过。

思路:AC自动机,和hdu2222思路其实是一样的,只不过这里就是需要增加一个域,来标记以该结点结束的串

#include<stdio.h>#include<string.h>const int MAXN = 200*500+10 ;int N , M ;char name[210] ;struct Node{int num ;//标记这个单词的标号 int f ;//表示是否是一个单词的结束 Node *fail ;Node *next[128] ;Node(){num = 0 ;f = 0 ;fail = NULL ;memset(next,  0 , sizeof(next)); }}*root ;int front, rear ;Node *que[MAXN] ;char str[10010] ;void build_trie(char *ch , int num){Node *loc = root ,*q;int idx ;for(int i=0;ch[i]!=0;i++){idx = ch[i] ;if(loc->next[idx] == NULL){q = new Node ;loc->next[idx] = q ;}loc = loc->next[idx] ;}loc->f = 1 ;loc->num = num ;}void build_automation(){front = rear = 0 ;Node *temp ,*q ;root->fail = NULL ;que[rear++] = root ;while(front != rear){temp = que[front++] ;for(int i=0;i<128;i++){if(temp->next[i] == NULL)continue ;if(temp == root){temp->next[i]->fail = root ;}else{q = temp->fail;while(q != NULL){if(q->next[i] != NULL){temp->next[i]->fail = q->next[i] ;break ;}q = q->fail;}if(q == NULL)temp->next[i]->fail = root ;}que[rear++] = temp->next[i] ;}}}bool one[510] ;void query(char *ch){Node *loc = root ,*q;int idx;for(int i=0;ch[i]!=0;i++){idx = str[i] ;while(loc!=root && loc->next[idx]==NULL)loc=loc->fail;loc = loc->next[idx] ;if(loc == NULL){loc = root ;}q = loc ;while(q != root){if(q->f){one[ q->num] = 1 ;}q = q->fail;}}}int main(){while(scanf("%d",&N) == 1){root = new Node ;for(int i=1;i<=N;i++){scanf("%s",name);build_trie(name , i) ;}build_automation(); scanf("%d",&M);int res = 0 ;for(int i=1;i<=M;i++){scanf("%s",str);memset(one , 0 , sizeof(one));query(str);bool have = 0 ;for(int j=1;j<=N;j++){if( one[j] ){have = 1 ; break ;}}if(have){res++ ;printf("web %d:",i);for(int j=1;j<=N;j++){if( one[j] )printf(" %d",j);}printf("\n");}}printf("total: %d\n",res);}return 0 ;}

的标号。

代码:


原创粉丝点击