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 }
原文地址:https://www.cnblogs.com/ezyzy/p/6148713.html