标签:
hdu2896:
题意:有一些串是病毒串(模式串),标号1~n,给出m个待匹配串,问每个模式串中有哪些病毒串,从小到大输出,并求共有多少待匹配串含有病毒串
就是将AC自动机的模板改了一下,用模式串结尾结点记录下这是哪个模式串的结尾,在遍历时再排序输出即可
1 #include<stdio.h> 2 #include<string.h> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 const int maxm=520*250; 7 8 char s[10020],word[210]; 9 bool vis[maxm]; 10 int nxt[maxm][128-30],cnt[maxm],fail[maxm],size; 11 int ans[520],c; 12 13 int newnode(){ 14 memset(nxt[size],0,sizeof(nxt[size])); 15 fail[size]=cnt[size]=0; 16 return size++; 17 } 18 19 void insert(char s[],int k){ 20 int i,p=0; 21 for(i=0;s[i];i++){ 22 int &x=nxt[p][s[i]-30]; 23 p=x?x:x=newnode(); 24 } 25 cnt[p]=k; 26 } 27 28 void makenxt(){ 29 int i; 30 queue<int>q; 31 q.push(0); 32 while(!q.empty()){ 33 int u=q.front(); 34 q.pop(); 35 for(i=0;i<128-30;i++){ 36 int v=nxt[u][i]; 37 if(v==0)nxt[u][i]=nxt[fail[u]][i]; 38 else q.push(v); 39 if(u&&v){ 40 fail[v]=nxt[fail[u]][i]; 41 } 42 } 43 } 44 } 45 46 bool query(char s[]){ 47 int d=0; 48 bool f=0; 49 for(int i=0;s[i];i++){ 50 d=nxt[d][s[i]-30]; 51 int tmp=d; 52 while(tmp!=0){ 53 if(cnt[tmp]&&!vis[tmp]){ 54 f=1; 55 vis[tmp]=1; 56 ans[++c]=cnt[tmp]; 57 } 58 tmp=fail[tmp]; 59 } 60 } 61 return f; 62 } 63 64 int main(){ 65 int n,m,i; 66 while(scanf("%d",&n)!=EOF){ 67 memset(cnt,0,sizeof(cnt)); 68 size=0,newnode(); 69 for(i=1;i<=n;i++){ 70 scanf("%s",word); 71 insert(word,i); 72 } 73 makenxt(); 74 scanf("%d",&m); 75 int res=0; 76 for(i=1;i<=m;i++){ 77 memset(vis,0,sizeof(vis)); 78 c=0; 79 scanf("%s",s); 80 if(query(s)){ 81 res++; 82 sort(ans+1,ans+c+1); 83 printf("web %d:",i); 84 for(int j=1;j<=c;j++){ 85 printf(" %d",ans[j]); 86 } 87 printf("\n"); 88 } 89 } 90 printf("total: %d\n",res); 91 } 92 return 0; 93 }
标签:
原文地址:http://www.cnblogs.com/cenariusxz/p/4510986.html