luogu2444 [POI2000]病毒

搞上一棵AC自动机,想让它无限匹配,dfs找环即可

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
int n, len;
char a[30005];
queue<int> d;
bool vis[30005], tmp[30005];
struct ACzdj{
	int siz, s[30005][2], fai[30005], u, v;
	bool val[30005];
	void ins(){
		u = 0;
		len = strlen(a);
		for(int i=0; i<len; i++){
			v = a[i] - '0';
			if(!s[u][v])	s[u][v] = ++siz;
			u = s[u][v];
		}
		val[u] = true;
	}
	void getFail(){
		for(int i=0; i<=1; i++)
			if(s[0][i])
				d.push(s[0][i]);
		while(!d.empty()){
			u = d.front();
			d.pop();
			for(int i=0; i<=1; i++){
				v = s[u][i];
				if(v){
					fai[v] = s[fai[u]][i];
					d.push(v);
					val[v] |= val[fai[v]];
				}
				else	s[u][i] = s[fai[u]][i];
			}
		}
	}
	bool dfs(int x){
		tmp[x] = true;
		for(int i=0; i<=1; i++){
			u = s[x][i];
			if(tmp[u])	return true;
			if(vis[u] || val[u])	continue;
			vis[u] = true;
			if(dfs(u))	return true;
		}
		tmp[x] = false;
		return false;
	}
}ac;
int main(){
	cin>>n;
	for(int i=1; i<=n; i++)
		scanf("%s", a), ac.ins();
	ac.getFail();
	if(ac.dfs(0))	printf("TAK
");
	else	printf("NIE
");
	return 0;
}
原文地址:https://www.cnblogs.com/poorpool/p/8000737.html