hdu 2896 病毒侵袭(ac自动机)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2896
中文题就不说题意了。
还是差不多ac自动机的模版稍微改一下就可以了。
#include <iostream> #include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; const int M = 1e5 + 10; int ans , cnt , Next[M][130] , fail[M] , End[M] , a[5] , L , root , temp; char str[220] , sl[10010]; int newnode() { for(int i = 0 ; i < 130 ; i++) { Next[L][i] = -1; } End[L++] = 0; return L - 1; } void init() { L = 0; root = newnode(); } void build(char s[]) { int len = strlen(s); int now = root; for(int i = 0 ; i < len ; i++) { int id = (int)s[i]; if(Next[now][id] == -1) { Next[now][id] = newnode(); } now = Next[now][id]; } End[now] = ++ans; } void get_fail() { queue<int>q; int now = root; fail[root] = root; for(int i = 0 ; i < 130 ; i++) { if(Next[root][i] == -1) { Next[root][i] = root; } else { fail[Next[root][i]] = root; q.push(Next[root][i]); } } while(!q.empty()) { int now = q.front(); q.pop(); for(int i = 0 ; i < 130 ; i++) { if(Next[now][i] == -1) { Next[now][i] = Next[fail[now]][i]; } else { fail[Next[now][i]] = Next[fail[now]][i]; q.push(Next[now][i]); } } } } int match(char s[]) { int len = strlen(s); int now = root; temp = 0; memset(a , 0 , sizeof(a)); for(int i = 0 ; i < len ; i++) { int id = (int)s[i]; now = Next[now][id]; int tem = now; while(tem != root) { if(End[tem] > 0) { a[temp++] = End[tem]; } tem = fail[tem]; } } sort(a , a + temp); if(temp) return 1; else return 0; } int main() { int n; scanf("%d" , &n); getchar(); init(); ans = 0 , cnt = 0; for(int i = 0 ; i < n ; i++) { gets(str); build(str); } get_fail(); int m; scanf("%d" , &m); getchar(); for(int i = 0 ; i < m ; i++) { gets(sl); if(match(sl)) { printf("web %d:" , i + 1); for(int j = 0 ; j < temp ; j++) { printf(" %d" , a[j]); } printf("\n"); cnt++; } } printf("total: %d\n" , cnt); return 0; }