【题目链接】
【题意】
寻找一个没有模式串为子串的无限01串。是否存在。
【题解】
其实就是用dfs找一个环。
1、环需要从根结点出发找到这个位置。且重新能走到这里,我们开一个“预测路径”的数组进行标记即可。
2、如果下一个结点碰上了“走过”标记过的,而不是“预测路径”,或者是模式串结尾,我们就避开不走。
注意:
fail数组是可以进行传递的,就是说fail指向的结点,同时是模式串的结尾,那么该位置也是不合法的。
最后看看代码怎么实现就明白了。

1 #include<cstdio>
2 #include<cstring>
3 #include<algorithm>
4
5 using namespace std;
6
7 const int N = 2005;
8 const int M = 30005;
9
10 int Trie[M][2] , fail[M] , End[M], idx ;
11 int Q[M] , Head , Tail ;
12 int vis[M],used[M];
13 int n ;
14
15 char str[N];
16
17 void Insert( char s[] ){
18 int p = 0;
19 for(int i=0 ; s[i] ; i++ ){
20 int t = s[i] - '0' ;
21 if( !Trie[p][t] )
22 Trie[p][t] = ++idx ;
23 p = Trie[p][t];
24 }
25 End[p] ++ ;
26 }
27
28 void Build(){
29 Head = 1 , Tail = 0 ;
30 for(int i=0;i<2;i++)
31 if(Trie[0][i])
32 Q[++Tail] = Trie[0][i] ;
33 //fail[Trie[0][i]] = 0;
34
35 while( Head <= Tail ){
36 int u = Q[Head++] ;
37 for(int i=0;i<2;i++){
38 int To = Trie[u][i];
39 if( To ){
40 fail[To] = Trie[fail[u]][i];
41 Q[++Tail] = To;
42
43 End[To] = End[To] || End[fail[To]] ;
44 }else{
45 Trie[u][i] = Trie[fail[u]][i];
46 }
47 }
48 }
49
50 }
51
52 bool dfs(int u){
53 vis[u] = 1;
54 for(int i=0;i<=1;i++){
55 int To = Trie[u][i];
56 if( vis[To] ) return true;
57 if( used[To] || End[To] ) continue;
58 used[To] = 1 ;
59 if( dfs(To) ) return true ;
60 }
61 vis[u] = 0;
62 return false ;
63 }
64 int main()
65 {
66 scanf("%d",&n);
67 for(int i=0;i<n;i++){
68 scanf("%s",str);
69 Insert(str);
70 }
71 Build();
72 puts(dfs(0)?"TAK":"NIE");
73
74 return 0 ;
75 }
