bzoj 2938 AC自动机
根据题意建出trie图,代表单词的点不能走,直接或间接指向它的点也不能走。这样的话如果能在图中找到一个环的话就是TAK,否则是NIE。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #define N 30005 7 using namespace std; 8 int n;bool flag; 9 int ch[N][2]; 10 bool yes[N][2]; 11 char s[N];int cnt; 12 bool ok[N]; 13 void inn() 14 { 15 int now=0; 16 int l=strlen(s); 17 for(int i=0;i<l;i++) 18 { 19 if(!ch[now][s[i]-'0'])ch[now][s[i]-'0']=++cnt,yes[now][s[i]-'0']=1; 20 now=ch[now][s[i]-'0']; 21 } 22 ok[now]=1; 23 } 24 int f[N]; 25 int vis[N],in[N]; 26 queue<int>q; 27 void dfs(int x) 28 { 29 // cout<<x<<endl; 30 // cout<<in[1]<<"SS"<<endl; 31 vis[x]=1;in[x]=1; 32 for(int i=0;i<2;i++) 33 { 34 if(!vis[ch[x][i]]) 35 { 36 if(!ok[ch[x][i]]) 37 { 38 dfs(ch[x][i]); 39 } 40 } 41 else if(in[ch[x][i]]) 42 { 43 flag=1; 44 } 45 } 46 in[x]=0; 47 } 48 bool fail() 49 { 50 for(int i=0;i<2;i++)if(ch[0][i])q.push(ch[0][i]); 51 while(!q.empty()) 52 { 53 int tmp=q.front();q.pop(); 54 for(int i=0;i<2;i++) 55 { 56 int u=ch[tmp][i]; 57 if(!u) 58 { 59 ch[tmp][i]=ch[f[tmp]][i];continue; 60 } 61 f[u]=ch[f[tmp]][i]; 62 if(ok[f[u]])ok[u]=1; 63 q.push(u); 64 } 65 } 66 dfs(0); 67 if(flag)return 1; 68 return 0; 69 } 70 int main() 71 { 72 scanf("%d",&n); 73 for(int i=1;i<=n;i++) 74 { 75 scanf("%s",s);inn(); 76 } 77 //cout<<f[5]<<endl; 78 if(fail())puts("TAK"); 79 else puts("NIE"); 80 return 0; 81 }