HDU 2896 AC自动机 裸题

中文题题意不再赘述

注意字符范围是可见字符,从32开始到95

char c - 32

 

#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
using namespace std;
inline int Max(int a,int b){return a>b?a:b;}
inline int Min(int a,int b){return a>b?b:a;}

#define N 10000
#define maxnode 57000
#define sigma_size 95
int pre[3];
struct Trie{
	int ch[maxnode][sigma_size];
	int val[maxnode];
	int f[maxnode];
	int sz;
	void init(){
		sz=1;
		memset(ch[0],0,sizeof(ch[0]));
		val[0] = 0;
	}
	int idx(char c){
		return c-32;
	}

	void Creat(char *s, int num){  
		int u = 0, len = strlen(s);  
		for(int i = 0; i < len; i++){  
			int c = idx(s[i]);  
			if(!ch[u][c]){ memset(ch[sz],0,sizeof(ch[sz])); val[sz]=0; ch[u][c] = sz++;  }
			u = ch[u][c];        
		}  
		val[u]  = num ; //u若是单词结尾则为 +1
	}  

	int find(char *T, int num){
		int len = strlen(T);
		int j = 0;
		int fir = 0;
		f[0] = 0;
		for(int i = 0; i < len; i++){
			int c = idx(T[i]);

			j = ch[j][c];
			if(!j) j = ch[0][c];
			int temp = j;
			while(temp && val[temp]){

				if(!fir) printf("web %d:", num);
				
				pre[fir++] = val[j];
				if(fir == 3)break;

				temp = f[temp];
			}
		}

		if(fir){
			sort(pre, pre+fir);
			for(int k = 0; k < fir; k++)printf(" %d",pre[k]);
			printf("\n");
		}
		return fir>0;
	}

	void getFail(){
		queue<int> q;
		f[0] = 0;
		//初始化队列
		for(int c = 0; c < sigma_size; c++)
			if(ch[0][c])q.push(ch[0][c]);

		while(!q.empty()){
			int r = q.front(); q.pop();
			for(int c = 0; c < sigma_size; c++){
				int u = ch[r][c];
				if(!u){ ch[r][c] = ch[f[r]][c]; continue; }
				q.push(u);
				int v = f[r];
				while(v && !ch[v][c]) v = f[v]; //沿失配边追溯到可以匹配的(非原点)位置
				f[u] = ch[v][c];
			}
		}
	}
};
Trie ac;
char S1[N],S2[N];

void InputString(){	
	gets(S1);

}
int main(){

	int n;

	while(~scanf("%d",&n)){
		ac.init();
		getchar();
		for(int i = 1; i <= n; i++){
			InputString();
			ac.Creat(S1, i);
		}
		ac.getFail();

		int ANS = 0;
		scanf("%d",&n);
		getchar();
		for(int i = 1; i <= n; i++){
		InputString();
		ANS += ac.find(S1, i);
		}
		printf("total: %d\n",ANS);
	}
	return 0;
}
/*  
3  
a aa  
bbb  
ccc  
2  
a aabbbccc  
bbaacc  
  
ans:  
web 1: 1 2 3
total: 1
  
*/  


 

 

posted @ 2013-10-08 21:36  pangbangb  阅读(142)  评论(0编辑  收藏  举报