P2444 [POI2000]病毒

ps:注意一点,如果一个节点的fail指针指向的是危险节点,那么这个节点也是危险节点。

const int N = 30005;

struct node {
    int fail, Count, vis[2];
    node () {
        fail = Count = 0;
        vis[0] = vis[1] = 0;
    }
};

struct AcAutomation {
    int cnt;
    node a[N];
    bool use[N], pa[N];

    void Inite() {
        cnt = 0;
        mem(pa, 0);
        mem(use, 0);
    }

    void Build(char *s) {
        int n = strlen(s);
        int now = 0;
        rep(i, 0, n) {
            int id = s[i] - '0';
            if (!a[now].vis[id]) a[now].vis[id] = ++cnt;
            now = a[now].vis[id];
        }
        a[now].Count++;
    }

    void getFail() {
        queue<int> q;
        rep(i, 0, 2) if (a[0].vis[i]) {
            a[a[0].vis[i]].fail = 0;
            q.push(a[0].vis[i]);
        }
        while(!q.empty()) {
            int now = q.front();
            q.pop();

            rep(i, 0, 2) {
                if (a[now].vis[i]) {
                    a[a[now].vis[i]].fail = a[a[now].fail].vis[i];
                    q.push(a[now].vis[i]);
                    if (a[a[a[now].fail].vis[i]].Count) a[a[now].vis[i]].Count++;
                }
                else {
                    a[now].vis[i] = a[a[now].fail].vis[i];
                }
            }
        }
    }

    bool DFS(int now = 0) {
        use[now] = 1;
        rep(i, 0, 2) {
            if (use[a[now].vis[i]]) {
                puts("TAK");
                exit(0);
            }
            else if (!a[a[now].vis[i]].Count) {
                //pa[a[now].vis[i]] = 1;
                DFS(a[now].vis[i]);
            }
        }
        use[now] = 0;
    }
};

int n;
char s[N];
AcAutomation Ac;

int main()
{
    sc(n);
    Ac.Inite();
    rep(i, 0, n) {
        scanf("%s", s);
        Ac.Build(s);
    }
    Ac.getFail();
    Ac.DFS();
    puts("NIE");
    return 0;
}

 

posted @ 2018-09-23 20:15  天之道,利而不害  阅读(255)  评论(0编辑  收藏  举报