hdu 2896 AC自动机模版题

题意:输出出现模式串的id,还是用end记录id就可以了。

本题有个关键点:“以上字符串中字符都是ASCII码可见字符(不包括回车)。”  -----也就说AC自动机的Trie树需要128个单词分支。

 

#include <cstdio>

#include <cstring>

#include <queue>



using namespace std;



const int maxw = 210 *500 + 10;

const int sigma_size = 128;

const int maxl = 10000 + 10;



struct Trie{

	int next[maxw][sigma_size],fail[maxw],end[maxw];

	int root,L;

	int newnode(){

		for(int i=0;i<sigma_size;i++)

		    next[L][i]=-1;

		end[L++]=-1;

		return L-1;

	}

	void init(){

		L=0;

		root=newnode();

	}

	void insert(const char *s,int id){

		int now=root,len=strlen(s);

		for(int i=0;i<len;i++){

			if(next[now][s[i]]==-1)

			    next[now][s[i]]=newnode();

			now=next[now][s[i]];

		}

		end[now]=id;

	}

	void build(){

		queue<int>Q;

		fail[root]=root;

		for(int i=0;i<sigma_size;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<sigma_size;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]);

			    }

		}

	}

	bool used[500 + 10];

	bool query(const char *buf,int n,int id){

		int now=root,len=strlen(buf);

		memset(used,false,sizeof(used));

		bool flag =false;

		for(int i=0;i<len;i++){

			now=next[now][buf[i]];

			int tmp=now;

			while(tmp!=root){

				if(end[tmp]!=-1){

					used[end[tmp]]=true;

					flag=true;

				}

			tmp=fail[tmp];

			}

		}

		if(!flag) return false;

		printf("web %d:",id);

		for(int i=1;i<=n;i++)

		    if(used[i])    printf(" %d",i);

		printf("\n");

		return true;

	}

};



char buf[maxl];

Trie ac;



int main()

{

	int n,m;

	while(~scanf("%d",&n)){

		ac.init();

		for(int i=1;i<=n;i++){

			scanf("%s",buf);

			ac.insert(buf,i);

		}

		ac.build();

		int ans=0;

		scanf("%d",&m);

		for(int i=1;i<=m;i++){

			scanf("%s",buf);

			if(ac.query(buf,n,i))  ans++;

		}

		printf("total: %d\n",ans);

	}

	return 0;

}


 

 

你可能感兴趣的:(AC自动机)