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. 基于NPOI的Excel数据导入

    从Excel导入数据最令人头疼的是数据格式的兼容性,特别是日期类型的兼容性.为了能够无脑导入日期,折腾了一天的NPOI.在经过测试确实可以导入任意格式的合法日期后,写下这篇小文,与大家共享.完整代码请 ...

  2. 彻底理解session

    最详细的对session的解析: https://www.tooto.cc/archives/178

  3. C# MD5加密

    public static string Encrypt(string txt) { System.Security.Cryptography.MD5CryptoServiceProvider md5 ...

  4. IOS中的编码规范

    1.指导原则 [原则1-]首先是为人编写程序,其次才是计算机. 说明:这是软件开发的基本要点,软件的生命周期贯穿产品的开发.测试.生产.用户使用.版本升级和后期维护等长期过程,只有易读.易维护的软件代 ...

  5. oracle 锁表查询与解锁

    查询锁住的表 SELECT s.sid, s.serial#, s.username, s.schemaname, s.osuser, s.process, s.machine,s.terminal, ...

  6. 孙鑫MFC学习笔记5:文本显示

    1.CreateSolidCaret添加一个插入符 参数:宽度,高度 如果设为0,就设为默认窗口边界的宽度和高度 2.GetSystemMetrics获取默认窗口边界的宽度和高度 3.Caret在创建 ...

  7. 转载:冷门js技巧

    前端已经被玩儿坏了!像console.log()可以向控制台输出图片等炫酷的玩意已经不是什么新闻了,像用||操作符给变量赋默认值也是人尽皆知的旧闻了,今天看到Quora上一个帖子,瞬间又GET了好多前 ...

  8. 使用python-openCV对摄像头捕捉的镜头进行二值化并打上文字

    用CaptureFromCAM函数对图像进行提取: capture = cv.CaptureFromCAM(0) 读取直接的视频文件只需将语句改变为: capture = cv.VideoCaptur ...

  9. Java获取服务器网址

    StringBuffer url1 = request.getRequestURL(); String tempContextUrl1 = url1.delete(url1.length() - re ...

  10. PMBOK/CMM/CMMI/OPM3

    1968年为了解决大型软件项目的软件危机,北大西洋公约组织(NATO)提出了“软件工程”这一术语,以改进软件开发设计过程. 1969年美国项目管理协会(PMI)组织成立,从1981年起经过30年的努力 ...