bzoj2938 病毒

在Trie图上找环,若有环则说明可以组成一个无限长的串

 1 #include<queue>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 int n,tot;
 7 char s[300005];
 8 bool ed[300005];
 9 bool usd[300005];
10 bool vis[300005];
11 struct Tree{
12     int son[2];
13     int fail;
14 }tr[300005];
15 void build(char h[]){
16     int len=strlen(h+1);
17     int now=0;
18     for(int i=1;i<=len;i++){
19         int k=h[i]-'0';
20         if(!tr[now].son[k])tr[now].son[k]=++tot;
21         now=tr[now].son[k];
22     }
23     ed[now]=true;
24 }
25 void getfail(){
26     queue<int>que;
27     if(tr[0].son[1])que.push(tr[0].son[1]);
28     if(tr[0].son[0])que.push(tr[0].son[0]);
29     while(!que.empty()){
30         int u=que.front();
31         que.pop();
32         for(int i=0;i<=1;i++){
33             if(tr[u].son[i]){
34                 tr[tr[u].son[i]].fail=tr[tr[u].fail].son[i];
35                 ed[tr[u].son[i]]|=ed[tr[tr[u].fail].son[i]];
36                 que.push(tr[u].son[i]);
37             }
38             else tr[u].son[i]=tr[tr[u].fail].son[i];
39         }
40     }
41 }
42 bool dfs(int u){
43     if(ed[u])return false;
44     vis[u]=true;bool ret=false;
45     for(int i=0;i<=1;i++){
46         if(vis[tr[u].son[i]])ret=true;
47         if(usd[tr[u].son[i]])continue;
48         usd[tr[u].son[i]]=true;
49         if(dfs(tr[u].son[i]))ret=true;
50     }
51     vis[u]=false;
52     return ret;
53 }
54 int main(){
55     scanf("%d",&n);
56     for(int i=1;i<=n;i++){
57         scanf("%s",s+1);
58         build(s);
59     }
60     getfail();
61     if(dfs(0))printf("TAK
");
62     else printf("NIE
");
63     return 0;
64 }
原文地址:https://www.cnblogs.com/lnxcj/p/10012129.html