【AC自动机】 HDOJ 2896 病毒侵袭

AC自动机的模板题~~~建个AC自动机的树,然后对网站的那个字符串挨个做匹配就行了。。。

#include <iostream>
#include <sstream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <climits>
#define maxn 10005
#define eps 1e-6
#define mod 10007
#define INF 99999999
#define lowbit(x) (x&(-x))
//#define lson o<<1, L, mid
//#define rson o<<1 | 1, mid+1, R
typedef long long LL;
using namespace std;

struct node
{
	int number;
	struct node *fail, *next[128];
	node() {
		number = 0;
		fail = NULL;
		for(int i = 0; i < 128; i++)
			next[i] = NULL;
	}
}*root, *tmp, *now, *p;
queue<node*> q;
char s[maxn];
int vec[maxn];
int n, m;

void insert(int x)
{
	int len = strlen(s), i, temp;
	now = root;
	for(i = 0; i < len; i++) {
		temp = s[i];
		if(!now->next[temp])
			now->next[temp] = new struct node;
		now = now->next[temp];
	}
	now->number = x;
}
void read(void)
{
	int i;
	root = new struct node;
	for(i = 0; i < n; i++) {
		scanf("%s", s);
		insert(i + 1);
	}
}
void build(void)
{
	int i;
	root->fail = NULL;
	q.push(root);
	while(!q.empty()) {
		now = q.front();
		q.pop();
		for(i = 0; i < 128; i++) {
			if(!now->next[i]) continue;
			if(now == root) now->next[i]->fail = root;
			else {
				p = now->fail;
				while(p) {
					if(p->next[i]) {
						now->next[i]->fail = p->next[i];
						break;
					}
					p = p->fail;
				}
				if(!p) now->next[i]->fail = root;
			}
			q.push(now->next[i]);
		}
	}
}
int cmp(int a, int b)
{
	return a<b;
}
bool search(int x)
{
	int len = strlen(s), i, cnt = 0, temp;
	now = root;
	for(i = 0; i < len; i++) {
		temp = s[i];
		while(now != root && !now->next[temp]) now = now->fail;
		if(!now->next[temp]) continue;
		now = now->next[temp];
		if(now->number) vec[cnt++] = now->number;
	}
	if(!cnt) return false;
	sort(vec, vec + cnt, cmp);
	printf("web %d:", x);
	for(i = 0; i < cnt; i++)
		printf(" %d", vec[i]);
	printf("\n");
	return true;
}
void work(void)
{
	int i, ans = 0;
	scanf("%d", &m);
	for(i = 1; i <= m; i++) {
		scanf("%s", s);
		if(search(i)) ans++;
	}
	printf("total: %d\n", ans);
}
int main(void)
{
	while(scanf("%d", &n)!=EOF) {
		read();
		build();
		work();
	}
	return 0;
}


你可能感兴趣的:(【AC自动机】 HDOJ 2896 病毒侵袭)