BZOJ2938: [POI2000] virus

Description

Binary virus Review Committee recently discovered the following rule: certain defined binary string is the virus code. If there is no section of a piece of code in the virus code, then we say the code is safe. The Commission has now identified all of the virus code segment, ask whether there is an infinite secure binary code.
Example:
For example, if {011, 11, 00000} for the virus code segment, then a possible infinite security code is 010101 .... If {01, 11, 000 000} as the virus code segment, then there is an infinitely long security code.
task:
Please write a program:
l virus code is read;
l is determined whether there is an infinitely long security code;
l outputs the result

Input

The first line contains an integer n, the number of virus code segments. The following n rows and each row comprises a non-empty string of 01 - is a virus code segment. The total length of all the virus code segment is not more than 30,000.

Output

You should output a word in the first line of the text file WIN.OUT:
l TAK-- If there is a code;
If there l NIE--.

Sample Input

3
01
11
00000

Sample Output

NO
 
Ideas: 
First of all viruses build a string AC automaton. 
Imagine an infinitely long security code exists, then take it to the AC automaton match, it would have been matched but have been unsuccessful match. 
That is, when the matching is not matched to End Node 1 (set X), and the end point of a pointer to fail (referred to y) can not be matched because of root..x a root..y suffix. 
And to infinite, that has been matched, it shows in the matching process will encounter a loop. 
So that is AC automaton point of view there is no ring on the line.

Feeling each do one AC automaton question on the re-learn it again AC automaton

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int p=10007;
const int N=1e6+10;
const int M=5e5+10;
int n,T;
char s[N];
struct acmach
{
    int Next[M][2],Fail[M];
    bool End[M];
    bool vis[N],in[N];
    int root,L;
    int newnode()
    {
        for (int i=0;i<2;i++) Next[L][i]=-1;
        End[L]=0;
        return L++;
    }
    void init()
    {
        L=0;
        root=newnode();
        for (int i=0;i<N;i++) vis[i]=in[i]=0;
    }
    void Insert(char s[])
    {
        int len=strlen(s);
        int now=root;
        for (int i=0;i<len;i++)
        {
            if (Next[now][s[i]-'0']==-1)
                Next[now][s[i]-'0']=newnode();
            now=Next[now][s[i]-'0'];
        }
        End[now]=1;
    }
    void build()
    {
        queue<int>q;
        Fail[root]=root;    
        for (int i=0;i<2;i++)
        if (Next[root][i]==-1) Next[root][i]=root; 
        else
        {
            Fail[Next[root][i]]=root;
            q.push(Next[root][i]);
        }
        while (!q.empty())
        {
            int now=q.front(); q.pop();
            End[now]|=End[Fail[now]];   //对于File指向End的点也不能访问到
            for (int i=0;i<2;i++)
            if (Next[now][i]==-1) Next[now][i]=Next[Fail[now]][i]; 
            else
            {
                Fail[Next[now][i]]=Next[Fail[now]][i]; 
                q.push(Next[now][i]);
            }
        }
    }
    bool dfs(int x)
    {
        in[x]=1;
        for (int i=0;i<2;i++)
        {
            int v=Next[x][i];
            if (in[v]) return 1;
            if (vis[v] || End[v]) continue;
            vis[v]=1;
            if (dfs(v)) return 1;
        }
        in[x]=0;
        return 0;
    }
}ac;
int main()
{
    ac.init();
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%s",s);
        ac.Insert(s);
    }
    ac.build();
    if (ac.dfs(ac.root)) printf("TAK\n");
    else printf("NIE\n");

    return 0;
}
View Code

Guess you like

Origin www.cnblogs.com/tetew/p/11545214.html