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];
struct EdgeNode{int next,to;}edge[MAXN<<];
int head[MAXN],cnt=,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'
int son[MAXN][],end[MAXN],sz=,fail[MAXN];
inline void Insert(char str[])
{
int len=strlen(str+),now=;
for (int i=; 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<int>q; q.push();
while (!q.empty())
{
int now=q.front(); q.pop();
end[now]|=end[fail[now]];
for (int i=; 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]);
else son[now][i]=fa? son[fa][i]:;
}
}
}
}
using namespace ACMachine;
inline bool Topo()
{
queue<int>q;
int sum=;
for (int i=; i<=sz; i++)
{
if (end[i]) sum++; else
for (int j=; j<=; j++)
if (!end[son[i][j]]) InsertEdge(i,son[i][j]);
}
for (int i=; 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);
for (int i=; i<=N; i++) scanf("%s",s+),Insert(s);
Getfail();
if (Topo()) puts("NIE"); else puts("TAK");
return ;
}

【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_1916_[Usaco2010 Open]冲浪_分层图+拓扑排序+DP

    BZOJ_1916_[Usaco2010 Open]冲浪_分层图+拓扑排序+DP Description 受到秘鲁的马丘比丘的新式水上乐园的启发,Farmer John决定也为奶牛们建 一个水上乐园. ...

  5. BZOJ_4383_[POI2015]Pustynia_线段树优化建图+拓扑排序

    BZOJ_4383_[POI2015]Pustynia_线段树优化建图+拓扑排序 Description 给定一个长度为n的正整数序列a,每个数都在1到10^9范围内,告诉你其中s个数,并给出m条信息 ...

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

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

  7. [POI2015][bzoj4383] Pustynia [线段树优化建图+拓扑排序]

    题面 bzoj权限题传送门 luogu传送门 思路 首先,这个题目显然可以从所有小的点往大的连边,然后如果没环就一定可行,从起点(入读为0)开始构造就好了 但是问题来了,如果每个都连的话,本题中边数是 ...

  8. [USACO12DEC]第一!First! (Trie树,拓扑排序)

    题目链接 Solution 感觉比较巧的题啊... 考虑几点: 可以交换无数次字母表,即字母表可以为任意形态. 对于以其他字符串为前缀的字符串,我们可以直接舍去. 因为此时它所包含的前缀的字典序绝对比 ...

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

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

随机推荐

  1. 解决springmvc+mybatis+mysql中文乱码问题【转】

    这篇文章主要介绍了解决java中springmvc+mybatis+mysql中文乱码问题的相关资料,需要的朋友可以参考下 近日使用ajax请求springmvc后台查询mysql数据库,页面显示中文 ...

  2. 在网站开发中很有用的8个 jQuery 效果【附源码】

    jQuery 作为最优秀 JavaScript 库之一,改变了很多人编写 JavaScript 的方式.它简化了 HTML 文档遍历,事件处理,动画和 Ajax 交互,而且有成千上万的成熟 jQuer ...

  3. JavaScript Array数组方法详解

    Array类型是ECMAScript中最常用的引用类型.ECMAScript中的数据与其它大多数语言中的数组有着相当大的区别.虽然ECMAScript中的数据与其它语言中的数组一样都是数据的有序列表, ...

  4. SAP CRM 复用视图

    在设计任何视图或组件的时候,我们需要以可复用的方式来设计它.UI组件设计的主要目标即可复用. 例如:几乎每个事务都要处理合作伙伴(客户).如果我们想要在Web UI显示那些合作伙伴,需要设计一个视图. ...

  5. Linux Distribution / ROM

    Linux发行版 http://unix.stackexchange.com/questions/87011/how-to-easily-build-your-own-linux-distro 这个文 ...

  6. C# 在Repeater 的ItemDataBound 如何转换e.Item.DataItem 的类型

    1.使用DataSet和DataTable绑定数据源时,用 DataRowView view = (DataRowView)e.Item.DataItem; 2.DataReader绑定数据源时,用 ...

  7. 【译】Spring 4 @PropertySource和@Value注解示例

    前言 译文链接:http://websystique.com/spring/spring-propertysource-value-annotations-example/ 本篇文章将展示如何通过@P ...

  8. 原创 C++作用域 (二)

    2.3全局作用域 2.3.1概述 全局作用域是最大的名字空间作用域,不同于用户自定义的名字空间作用域,全局作用域不需要显示地定义,它天然存在于C++程序中.全局作用域是一个最外层的容器,是所有作用域的 ...

  9. HTML之DocType的几种类型 -转载

    HTML之DocType的几种类型转载 doctype类型详细doctype的几种类型html之doctype 分类: 前端文摘  在默认情况下,FF和IE的解释标准是不一样的,也就是说,如果一个网页 ...

  10. Centos 6.5 Percona 5.6.27 Tokudb 配置

    参考 https://www.percona.com/doc/percona-server/5.6/tokudb/tokudb_installation.html # wget https://www ...