BZOJ2938 POI2000病毒

我们不能让重复过的字串出现在无限串上(就叫这个了。。。)

也就是要自动机一直能匹配但就是匹配不到,那么就是在自动机上找一个环。

dfs判环即可。注意是个有向图。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=30005;
 4 struct node
 5 {
 6     int v[3],f,s;
 7 }t[N];
 8 int n,cnt;
 9 queue<int>q;
10 char s[1000005];
11 void build()
12 {
13     int l=strlen(s);int now=0;
14     for(int i=0;i<l;++i)
15     {
16         if(t[now].v[s[i]-'0']){
17             now=t[now].v[s[i]-'0'];
18         }
19         else{
20             now=t[now].v[s[i]-'0']=++cnt;
21         }
22     }
23     t[now].s++;
24 }
25 void getfail()
26 {
27     for(int i=0;i<2;++i)
28     {
29         if(t[0].v[i])q.push(t[0].v[i]),t[t[0].v[i]].f=0;
30     }
31     while(!q.empty())
32     {
33         int x=q.front();q.pop();
34         for(int i=0;i<2;++i)
35         {
36             if(t[x].v[i]){
37                 q.push(t[x].v[i]);
38                 t[t[x].v[i]].f=t[t[x].f].v[i];
39                 t[t[x].v[i]].s|=t[t[t[x].v[i]].f].s;//我们不是统计个数而是坚决拒绝结束标记的存在
40             }
41             else{
42                 t[x].v[i]=t[t[x].f].v[i];
43             }
44         }
45     }
46 }
47 bool in[N],v[N];
48 bool dfs(int x)
49 {
50     in[x]=1;
51     for(int i=0;i<2;++i)
52     {
53         int y=t[x].v[i];
54         if(in[y])return 1;
55         if(t[y].s||v[y])continue;
56         v[y]=1;
57         if(dfs(y))return 1;
58     }
59     in[x]=0;return 0;
60 }
61 int main()
62 {
63     scanf("%d",&n);
64     for(int i=1;i<=n;++i)
65     {
66         scanf("%s",s);
67         build();
68     }
69     getfail();
70     if(dfs(0))puts("TAK");
71     else puts("NIE");
72     return 0;
73 }

 

posted @ 2018-01-22 10:49  大奕哥&VANE  阅读(171)  评论(0编辑  收藏  举报