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)

posted @ 2019-08-08 12:32  lahlah  阅读(28)  评论(0编辑  收藏  举报