您的位置:首页 > 其它

bzoj2938: [Poi2000]病毒

2018-07-12 21:27 537 查看

题目链接

bzoj2938: [Poi2000]病毒

题解

简单的来说,就是构造一个只含0和1的字符串,不能与Trie完成匹配。

dfs判一下trie图上是否存在与根节点相连没有串结尾的环

也就是有串结尾的点和fail指针指向串结尾的点,或指向不能走的点(也就是之前那一坨)的点也不能在环中

代码

#include<bits/stdc++.h>
using namespace std;
int n;
const int maxn = 30007;
char a[30007];
int ch[maxn][2],val[maxn];
int sz = 0;
void Insert(char *s) {
int len = strlen(s + 1),now = 0 ;
for(int i = 1;i <= len;++ i) {
int c = s[i] - '0';
if(!ch[now][c])
ch[now][c] = ++ sz;
now = ch[now][c];
}
val[now] = 1;
}
queue<int>q;
int fail[maxn];
void getfail() {
for(int i = 0;i <= 1;++ i) if(ch[0][i]) q.push(ch[0][i]);
while(!q.empty() ) {
int now = q.front();
q.pop();
for(int i = 0;i <= 1;++ i) {
if(ch[now][i]) {
fail[ch[now][i]] = ch[fail[now]][i];
val[ch[now][i]] |= val[ch[fail[now]][i]];
q.push(ch[now][i]);
}
else ch[now][i]  = ch[fail[now]][i];
}
}
}
bool vis[maxn],ht[maxn];
void dfs(int x) {
vis[x] = 1; ht[x] = 1;
for(int i =0;i <= 1;++ i) {
int v = ch[x][i];
if(v) {
if(vis[v]) {
puts("TAK");
exit(0);
}
if(!ht[v] && !val[v]) dfs(v);
}
}
vis[x] = 0;
}
int main() {
scanf("%d",&n);
for(int i = 1;i <= n;++ i) {
scanf("%s",a + 1);
Insert(a);
}
getfail();
dfs(0);
puts("NIE");
return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: