UVA 1449 - Dominating Patterns AC自动机
因为有重复,结点用vector保存单词编号。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<vector> #include<queue> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<algorithm> using namespace std; const int MAX_NODE=15000; const int SIGMA_SIZE=26; struct ACAutomation { int sz; int ch[MAX_NODE][SIGMA_SIZE]; int fail[MAX_NODE]; vector<int> val[MAX_NODE]; void init() { sz=1; memset(ch[0],0,sizeof(ch[0])); val[0].clear(); } int idx(char c){return c-'a';} void insert(const char *s,int v) { int u=0; for(int i=0;s[i]!='\0';i++) { int v=idx(s[i]); if(!ch[u][v]) { memset(ch[sz],0,sizeof(ch[sz])); val[sz].clear(); ch[u][v]=sz++; } u=ch[u][v]; } val[u].push_back(v); } void construct() { fail[0]=0; queue<int> q; for(int c=0;c<SIGMA_SIZE;c++) { int u=ch[0][c]; if(u){fail[u]=0;q.push(u);} } 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[fail[r]][c];continue;} q.push(u); int v=fail[r]; while(v&&!ch[v][c])v=fail[v]; fail[u]=ch[v][c]; } } } void count(int u,int *da) { for(int i=0;i<val[u].size();i++) da[val[u][i]]++; if(!val[fail[u]].empty())count(fail[u],da); } void find(const char *s,int *da) { int u=0; for(int i=0;s[i]!='\0';i++) { int v=idx(s[i]); u=ch[u][v]; if(!val[u].empty())count(u,da); } } }; ACAutomation ac; int n; char dic[200][100]; char T[1000100]; int num[200]; int main() { while(scanf("%d",&n)!=EOF&&n) { ac.init(); for(int i=1;i<=n;i++) { scanf("%s",dic[i]); ac.insert(dic[i],i); } ac.construct(); scanf("%s",T); memset(num,0,sizeof(num)); ac.find(T,num); int maxx=0; for(int i=1;i<=n;i++) maxx=max(maxx,num[i]); printf("%d\n",maxx); for(int i=1;i<=n;i++) if(num[i]==maxx)printf("%s\n",dic[i]); } return 0; }