2938: [Poi2000]病毒

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 609  Solved: 318
[Submit][Status][Discuss]

Description

二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码。如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的。现在委员会已经找出了所有的病毒代码段,试问,是否存在一个无限长的安全的二进制代码。
示例:
例如如果{011, 11, 00000}为病毒代码段,那么一个可能的无限长安全代码就是010101…。如果{01, 11, 000000}为病毒代码段,那么就不存在一个无限长的安全代码。
任务:
请写一个程序:
l         读入病毒代码;
l         判断是否存在一个无限长的安全代码;
l         将结果输出

Input

第一行包括一个整数n,表示病毒代码段的数目。以下的n行每一行都包括一个非空的01字符串——就是一个病毒代码段。所有病毒代码段的总长度不超过30000。

Output

你应在在文本文件WIN.OUT的第一行输出一个单词:
l         TAK——假如存在这样的代码;
l         NIE——如果不存在。

Sample Input

3
01
11
00000

Sample Output

NIE

HINT

Source

Solution

Trie图的一大经典应用。

要构造一个无限长的安全串,显然是需要找至少一个安全的子串,然后循环下去,问题在于是否存在这样的子串。

建出Trie图之后,满足条件的子串必须在Trie图上不断匹配,而且不断失配无法达到危险节点。

这就说明,Trie图中存在不经过危险节点的环! 然后进行拓扑排序即可。

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
#define MAXN 30010
int N;
char s[MAXN];
];
,d[MAXN],visit[MAXN];
inline void AddEdge(int u,int v) {cnt++; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v;}
inline void InsertEdge(int u,int v) {AddEdge(u,v); d[v]++; /*printf("%d ---> %d\n",u,v);*/}
namespace ACMachine
{
    #define id(s) s-'0'
    ],end[MAXN],sz=,fail[MAXN];
    inline void Insert(char str[])
    {
        ),now=;
        ; i<=len; i++)
            if (son[now][id(str[i])]) now=son[now][id(str[i])];
                else son[now][id(str[i])]=++sz,now=sz;
        end[now]=;
    }
    inline void Getfail()
    {
        queue<);
        while (!q.empty())
            {
                int now=q.front(); q.pop();
                end[now]|=end[fail[now]];
                ; i<=; i++)
                        {
                            int fa=fail[now];
                            while (fa && !son[fa][i]) fa=fail[fa];
                            if (son[now][i])
                                fail[son[now][i]]=fa? son[fa][i]:,q.push(son[now][i]);
                            ;
                        }
            }
    }
}
using namespace ACMachine;
inline bool Topo()
{
    queue<int>q;
    ;
    ; i<=sz; i++)
        {
            if (end[i]) sum++; else
            ; j<=; j++)
                if (!end[son[i][j]]) InsertEdge(i,son[i][j]);
        }
    ; i<=sz; i++) if (!d[i] && !end[i]) q.push(i);
    while (!q.empty())
        {
            int now=q.front(); q.pop(); sum++;
            for (int i=head[now]; i; i=edge[i].next)
                if (!--d[edge[i].to]) q.push(edge[i].to);
        }
    return sum==sz;
}
int main()
{
    scanf("%d",&N);
    ; i<=N; i++) scanf(),Insert(s);
    Getfail();
    if (Topo()) puts("NIE"); else puts("TAK");
    ;
}

【BZOJ-2938】病毒 Trie图 + 拓扑排序的更多相关文章

  1. Bzoj 1565: [NOI2009]植物大战僵尸 最大权闭合图,拓扑排序

    题目: http://cojs.tk/cogs/problem/problem.php?pid=410 410. [NOI2009] 植物大战僵尸 ★★★   输入文件:pvz.in   输出文件:p ...

  2. HDU4857——逃生(反向建图+拓扑排序)(BestCoder Round #1)

    逃生 Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前.同时,社会 ...

  3. POJ3687——Labeling Balls(反向建图+拓扑排序)

    Labeling Balls DescriptionWindy has N balls of distinct weights from 1 unit to N units. Now he tries ...

  4. BZOJ 2938: [Poi2000]病毒 [AC自动机 拓扑排序]

    2938: [Poi2000]病毒 题意:判断是否存在无限长的不含模式串的字符串.只有01. 建出套路DP的转移图,判断有环就行了 练习一下拓扑排序 #include <iostream> ...

  5. 图——拓扑排序(uva10305)

    John has n tasks to do. Unfortunately, the tasks are not independent and the execution of one task i ...

  6. poj 3683 2-sat建图+拓扑排序输出结果

    发现建图的方法各有不同,前面一题连边和这一题连边建图的点就不同,感觉这题的建图方案更好. 题意:给出每个婚礼的2个主持时间,每个婚礼的可能能会冲突,输出方案. 思路:n个婚礼,2*n个点,每组点是对称 ...

  7. bzoj 4010: [HNOI2015]菜肴制作 拓扑排序

    题目链接: 题目 4010: [HNOI2015]菜肴制作 Time Limit: 5 Sec Memory Limit: 512 MB 问题描述 知名美食家小 A被邀请至ATM 大酒店,为其品评菜肴 ...

  8. HDU 5438 拓扑排序+DFS

    Ponds Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Sub ...

  9. 有向无环图的应用—AOV网 和 拓扑排序

    有向无环图:无环的有向图,简称 DAG (Directed Acycline Graph) 图. 一个有向图的生成树是一个有向树,一个非连通有向图的若干强连通分量生成若干有向树,这些有向数形成生成森林 ...

随机推荐

  1. 2012 Multi-University #8

    DP+单调队列优化 E One hundred layer 题意:n*m的矩形,从第一层x位置往下走,每一层都可以往左或往右移动最多k步再往下走,问走到n层时所走路径的最大值. 分析:定义,,注意到m ...

  2. 创建和删除节点:——核心DOM

    1. 创建单个元素节点:3步:       1. 创建空元素节点对象:          var elem=document.createElement("标签名");      ...

  3. Android笔记:获取屏幕信息

    像素密度(dpi) float xdpi = getResources().getDisplayMetrics().xdpi;float ydpi = getResources().getDispla ...

  4. IOS开发之——登录加密也许用到的,反转字符串

    - (NSString *)stringByReversed{//    NSMutableString *s = [NSMutableString string];//    for (NSUInt ...

  5. ReactiveCocoa初步

    [self.usernameTextField.rac_textSignal subscribeNext:^(id x) { NSLog(@"%@", x); }]; 打印结果 - ...

  6. 在Linux上使用的10种云备份方案

    导读 不久前,为用户提供一种备份远程机器上数据的简易方法还很稀奇.现在,我们已觉得这理所当然.Dropbox及其他公司简化了这项任务.苹果.谷歌和微软都提供各自的数据备份方法. 在Linux上,情况有 ...

  7. git提交

    1.git pull 本地已经commit 2.git checkout master 3.git pull 4.git checkout - 5.git merge master 6.git pus ...

  8. 深入理解React(二) —— 数据流和事件原理

    版权声明:本文由左明原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/158 来源:腾云阁 https://www.qclou ...

  9. 项目管理软件---redmine安装配置

    redmine是一个开源的项目管理软件,其主页是:http://www.redmine.org redmine是基于Ruby on Rails框架的,跨平台和跨数据库. 安装过程 ========== ...

  10. PHP获取今天、昨天、明天的日期

    <?php echo "今天:".date("Y-m-d")."<br>"; echo "昨天:".d ...