HDU-2896 病毒侵袭(AC自动机)

题目大意:AC自动机模板题。

代码如下:

# include<iostream>
# include<cstdio>
# include<queue>
# include<string>
# include<cstring>
# include<algorithm>
using namespace std;

const int N=500;

int ch[N*150+5][95];
int val[N*150+5];
int f[N*150+5];
int cnt;
bool mark[505];

void init()
{
	cnt=0;
	memset(ch,0,sizeof(ch));
	memset(val,0,sizeof(val));
}

void insert(string str,int v)
{
	int root=0;
	for(int i=0;i<str.size();++i){
		if(!ch[root][str[i]-32]) ch[root][str[i]-32]=++cnt;
		root=ch[root][str[i]-32];
	}
	val[root]=v;
}

void getFail()
{
	queue<int>q;
	f[0]=0;
	for(int i=0;i<95;++i){
		int u=ch[0][i];
		if(u){
			f[u]=0;
			q.push(u);
		}
	}
	while(!q.empty()){
		int r=q.front();
		q.pop();
		for(int i=0;i<95;++i){
			if(ch[r][i]){
				q.push(ch[r][i]);
				f[ch[r][i]]=ch[f[r]][i];
			}else{
				ch[r][i]=ch[f[r]][i];
			}
		}
	}
}

bool ac(string str)
{
	int n=str.size();
	int j=0;
	bool flag=false;
	for(int i=0;i<n;++i){
		j=ch[j][str[i]-32];
		int u=j;
		while(u){
			if(val[u]){
				mark[val[u]]=true;
				flag=true;
			}
			u=f[u];
		}
	}
	return flag;
}

int main()
{
	int n,m;
	string str;
	while(~scanf("%d",&n))
	{
		init();
		for(int i=0;i<n;++i){
			cin>>str;
			insert(str,i+1);
		}
		getFail();
		scanf("%d",&m);
		int total=0;
		for(int i=0;i<m;++i){
			cin>>str;
			memset(mark,false,sizeof(mark));
			if(ac(str)){
				++total;
				printf("web %d:",i+1);
				for(int j=1;j<=n;++j) if(mark[j])
					printf(" %d",j);
				printf("\n");
			}
		}
		printf("total: %d\n",total);
	}
	return 0;
}

  

posted @ 2016-08-11 15:31  20143605  阅读(129)  评论(0编辑  收藏  举报