http://acm.hdu.edu.cn/showproblem.php?pid=2896
思路:建立字典树时,把字符串单词节点信息改为id就可以,然后计算失配函数,再查找哪一个上面的病毒字符串在下面的网站信息中出现,AC自动机。
1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #include <algorithm> 5 #include <vector> 6 #include <set> 7 using namespace std; 8 9 int n,m; 10 char str[2000000]; 11 set<int>g; 12 struct node 13 { 14 struct node *next[128],*fail; 15 int v; 16 }*root; 17 18 void insert(char str[],int v) 19 { 20 struct node *head=root; 21 struct node *temp; 22 int k=strlen(str); 23 for(int i=0; i<k; i++) 24 { 25 int x=(int)str[i]; 26 if(head->next[x]==NULL) 27 { 28 temp=(struct node *)malloc(sizeof(struct node)); 29 temp->v=0; 30 temp->fail=root; 31 for(int j=0; j<128; j++) 32 { 33 temp->next[j]=NULL; 34 } 35 head->next[x]=temp; 36 } 37 head=head->next[x]; 38 if(i==k-1) head->v=v; 39 } 40 } 41 42 void Build_AC() 43 { 44 struct node *head=root; 45 queue<node *>q; 46 q.push(root); 47 while(!q.empty()) 48 { 49 head=q.front(); 50 q.pop(); 51 for(int j=0; j<128; j++) 52 { 53 if(head->next[j]) 54 { 55 q.push(head->next[j]); 56 if(head==root) 57 { 58 head->next[j]->fail=root; 59 } 60 else 61 { 62 struct node *p=head->fail; 63 bool flag=false; 64 while(p->next[j]==NULL) 65 { 66 if(p==root) 67 { 68 flag=true; 69 break; 70 } 71 p=p->fail; 72 } 73 if(flag) 74 { 75 head->next[j]->fail=root; 76 } 77 else 78 { 79 head->next[j]->fail=p->next[j]; 80 } 81 } 82 } 83 } 84 } 85 } 86 87 void Find(char str[]) 88 { 89 struct node *head=root,*p; 90 int k=strlen(str); 91 for(int i=0; i<k; i++) 92 { 93 int x=(int)str[i]; 94 while(head->next[x]==NULL&&head!=root) head=head->fail; 95 if(head->next[x]==NULL) head=root; 96 else head=head->next[x]; 97 p=head; 98 while(p!=root) 99 { 100 if(p->v) 101 g.insert(p->v); 102 p=p->fail; 103 } 104 } 105 } 106 107 int main() 108 { 109 while(scanf("%d",&n)!=EOF) 110 { 111 root=(struct node*)malloc(sizeof(struct node)); 112 root->fail=root; 113 root->v=0; 114 for(int i=0; i<128; i++) 115 { 116 root->next[i]=NULL; 117 } 118 for(int i=1; i<=n; i++) 119 { 120 scanf("%s",str); 121 insert(str,i); 122 } 123 Build_AC(); 124 set<int>::iterator it; 125 int ans=0; 126 scanf("%d",&m); 127 for(int j=1; j<=m; j++) 128 { 129 g.clear(); 130 scanf("%s",str); 131 Find(str); 132 if(g.size()) 133 { 134 ans++; 135 printf("web %d:",j); 136 for(it=g.begin(); it!=g.end(); it++) 137 { 138 printf(" %d",*it); 139 } 140 printf(" "); 141 } 142 } 143 printf("total: %d ",ans); 144 } 145 return 0; 146 }