洛谷2444(Trie图上dfs判环)
要点
- 并没问具体方案,说明很可能不是构造。
- 思考不断读入这个文本串,然后中间不出现某些文法的串。啊,这就是个自动机。
- 将不合法串使用ac自动机构成一个Trie图,我们需要的字符串就是在这个自动机上无限走路但是却不会撞到危险节点。
- 这样只要从根开始跑dfs判有环即存在答案。
- 注意还要加上ac自动机的性质:某节点的fail指针指向的如果是危险的,则它也是危险的。"she"的'e'指向"he"的'e',说明she里有he,也是不可走。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <queue>
using namespace std;
const int maxn = 2005;
int n;
string s[maxn];
struct ac_auto {
int ch[30005][2];
int fail[30005];
bool mark[30005];
int vis[30005];
int sz;
void insert(string s) {
int now = 0;
for (int i = 0; i < s.length(); i++) {
int c = s[i] - '0';
if (!ch[now][c]) {
ch[now][c] = ++sz;
mark[sz] = 0;
}
now = ch[now][c];
}
mark[now] = 1;
}
void getfail() {
queue<int> Q;
for (int i = 0; i < 2; i++)
if (ch[0][i])
fail[ch[0][i]] = 0, Q.push(ch[0][i]);
while (!Q.empty()) {
int u = Q.front(); Q.pop();
for (int i = 0; i < 2; i++)
if (ch[u][i]) {
fail[ch[u][i]] = ch[fail[u]][i], Q.push(ch[u][i]);
if (mark[fail[ch[u][i]]]) mark[ch[u][i]] = 1;
}
else ch[u][i] = ch[fail[u]][i];
}
}
void dfs(int cur) {
vis[cur] = 1;
for (int i = 0; i < 2; i++) {
int to = ch[cur][i];
if (to) {
if (mark[to]) continue;
if (vis[to] == 1) {
cout << "TAK\n";
exit(0);
}
if (!vis[to]) dfs(to);
}
}
vis[cur] = 2;
}
}ac;
int main() {
ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> s[i];
ac.insert(s[i]);
}
ac.getfail();
ac.dfs(0);
cout << "NIE\n";
return 0;
}
洛谷2444(Trie图上dfs判环)的更多相关文章
- cf1278D——树的性质+并查集+线段树/DFS判环
昨天晚上本来想认真打一场的,,结果陪女朋友去了.. 回来之后看了看D,感觉有点思路,结果一直到现在才做出来 首先对所有线段按左端点排序,然后用并查集判所有边是否联通,即遍历每条边i,和前一条不覆盖它的 ...
- CodeForces 659E New Reform (图的遍历判环)
Description Berland has n cities connected by m bidirectional roads. No road connects a city to itse ...
- Atcoder Grand Contest 032C(欧拉回路,DFS判环)
#include<bits/stdc++.h>using namespace std;int vis[100007];vector<int>v[100007];vector&l ...
- 洛谷 P1379 八数码难题 Label:判重&&bfs
特别声明:紫书上抄来的代码,详见P198 题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给 ...
- 洛谷P1219 八皇后【dfs】
题目描述 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行.每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子. 上面的布局可以用序列2 4 6 1 3 ...
- 【BZOJ1064】[NOI2008] 假面舞会(图上DFS)
点此看题面 大致题意:有\(k\)种面具(\(k\)是一个未知数且\(k≥3\),每种面具可能有多个),已知戴第\(i\)种面具的人能看到第\(i+1\)种面具上的编号,特殊的,戴第\(k\)种面具的 ...
- 洛谷1378 油滴扩展 dfs进行回溯搜索
题目链接:https://www.luogu.com.cn/problem/P1378 题目中给出矩形的长宽和一些点,可以在每个点放油滴,油滴会扩展,直到触碰到矩形的周边或者其他油滴的边缘,求出剩余面 ...
- BZOJ2938 & 洛谷2444:[POI2000]病毒——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=2938 https://www.luogu.org/problemnew/show/P2444 二进制 ...
- cf374C Inna and Dima dfs判环+求最长链
题目大意是有一个DIMA四种字母组成的矩阵,要在矩阵中找最长的DIMADIMADIMA……串,连接方式为四方向连接,问最长能找到多少DIMA.字母可以重复访问,如果DIMA串成环,即可以取出无限长的D ...
随机推荐
- python学习笔记:第五天( 字典)
Python3 字典 字典是另一种可变容器模型,且可存储任意类型对象. 字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({})中 ,格 ...
- 一些rtsp实现的开源代码
* live.com C/S C++ http://www.live555.com * darwin S C++ http://www.opensource.a ...
- (转)linux 打开文件数 too many open files 解决方法
too many open files 出现这句提示的原因是程序打开的文件/socket连接数量超过系统设定值. 查看每个用户最大允许打开文件数量 ulimit -a fdipzone@ubuntu: ...
- 每天一个linux命令(1):man命令
版权声明 更新:2017-04-19博主:LuckyAlan联系:liuwenvip163@163.com声明:吃水不忘挖井人,转载请注明出处! 1 文章介绍 本文介绍了Linux下命令man. 2 ...
- WPF ListView VisualPanel
<ItemsPanelTemplate x:Key="ItemsPanelTemplate1"> &l ...
- 904E
$dp$ 凉凉.jpg 看到题就想决策单调性,想了一个多小时也没想出来,排名$200+$,$gg$ 事实上,我们只可能每$c$个或每一个分一段,假设我们分了一段长为$c$,如果添加一个新元素,如果新的 ...
- layout属性
RelativeLayout 第一类:属性值为true可false android:layout_centerHrizontal 水平居中 android:layout_centerVe ...
- ng2中router-outlet用法
说明:router-outlet 是应用中的路由插座,一个页面中可以使用一个或多个router-outlet 1.只使用一个router-outlet 父组件: <router-outlet&g ...
- 如何将Eclipse中编写的java项目导出?
转自:https://zhidao.baidu.com/question/347808396.html1.导入项目 当下载了包含Eclipse 项目的源代码文件后,我们可以把它导入到当前的Eclips ...
- [spoj694&spoj705]New Distinct Substrings(后缀数组)
题意:求字符串中不同子串的个数. 解题关键:每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同的前缀的个数. 1.总数减去height数组的和即可. 注意这里height中为什么不需 ...