luogu P2444 [POI2000]病毒
link: https://www.luogu.org/problem/P2444
题目大意
1.读入n个病毒代码;
2.判断是否存在一个无限长的安全代码(不包含病毒代码;
3.将结果输出
TAK——假如存在这样的代码;
NIE——如果不存在。
代码都是01串
直接把AC自动机建好,然后大力找环就好了
真TM水
我才不会告诉你这是我一年前挖的坑
#include<bits/stdc++.h>
#define N 30005
#define C 2
using namespace std;
int ch[N][C], nxt[N], vis[N], tot, viss[N], n, F;
string st;
void insert(){ //插♂入
int p = 0, len = st.length();
for(int i = 0; i < len; i ++){
if(!ch[p][st[i] - '0']) ch[p][st[i] - '0'] = ++ tot;
p = ch[p][st[i] - '0'];
}
vis[p] = 1;
}
queue<int> q;
void build(){//建AC自动机
for(int i = 0; i < C; i ++) if(ch[0][i]) q.push(ch[0][i]);
while(q.size()){
int u = q.front(); q.pop();
vis[u] |= vis[nxt[u]]; //继承标记
for(int i = 0; i < C; i ++){
if(ch[u][i]){
nxt[ch[u][i]] = ch[nxt[u]][i];
q.push(ch[u][i]);
}else ch[u][i] = ch[nxt[u]][i];
}
}
}
void dfs(int u){//大力找环
if(viss[u]) F = 1;
if(F) return;
viss[u] = 1;
for(int i = 0; i < C; i ++){
if(!vis[ch[u][i]]) dfs(ch[u][i]);//如果能走就走
}
viss[u] = 0;
}
int main(){
ios::sync_with_stdio(false);
cin >> n;
for(int i = 1; i <= n; i ++) cin >> st, insert();
build();
dfs(0);
if(F) cout << "TAK";
else cout << "NIE";
return 0;
}
emmmmm……好久没写blog了,后面可能会写很多篇(flag)