标签:ch trie POI2000 int flag P2444 fail now 病毒
链接
题解
这题问我们能否构造一个无限长的串使得所有模式串均无法匹配,也就是说这个长串会在AC自动机上绕来绕去,不经过任何一个模式串的结尾。所以在trie图中有两类结点不能经过:表示单词结尾的结点和fail指针指向单词结尾的结点。如果剩下的trie边和转移边能形成环,才能构造出题目要求的串。
然后就变成了一个图论问题,用DFS找环。洛谷的数据很水,错误复杂度的DFS也能过。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 9;
struct tnode
{
int ch[2];
int cnt, fail;
};
tnode trie[maxn];
int tot, n;
bool flag[maxn], vis[maxn], used[maxn];
void ins(string &s)
{
int len = s.length(), now = 0;
for (int i = 0; i < len; ++i)
{
int c = s[i] - '0';
if (!trie[now].ch[c])
trie[now].ch[c] = ++tot;
now = trie[now].ch[c];
}
flag[now] = 1;
}
void build()
{
queue<int> q;
if (trie[0].ch[0])
q.push(trie[0].ch[0]);
if (trie[0].ch[1])
q.push(trie[0].ch[1]);
while (!q.empty())
{
int u = q.front();
q.pop();
for (int i = 0; i < 2; ++i)
{
int &now = trie[u].ch[i];
if (now)
{
trie[now].fail = trie[trie[u].fail].ch[i];
flag[now] |= flag[trie[now].fail];
q.push(now);
}
else
{
now = trie[trie[u].fail].ch[i];
}
}
}
}
bool dfs(int now)
{
vis[now] = 1;
for (int i = 0; i < 2; ++i)
{
int &to = trie[now].ch[i];
if (vis[to])
return 1;
if (flag[to] || used[to])
continue;
used[to] = 1;
if (dfs(to))
return 1;
}
vis[now] = 0;
return 0;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n;
string s;
for (int i = 1; i <= n; ++i)
{
cin >> s;
ins(s);
}
build();
cout << (dfs(0) ? "TAK" : "NIE") << endl;
return 0;
}
标签:ch,trie,POI2000,int,flag,P2444,fail,now,病毒 来源: https://blog.csdn.net/Pastafarian/article/details/114739571
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。