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;
}