ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【字符串】#2938. [Poi2000]病毒

2022-08-31 18:30:26  阅读:138  来源: 互联网

标签:ch 2938 int tr Poi2000 dfs go 字符串 fail


分析

不难想到使用 Trie 图来模拟匹配的过程。

那么要求的就等价于:判断是否可以从 Trie 图的根节点 \(0\) 出发不经过非法节点找到一个环。

非法节点则等价于:插入的模式串在 Trie 中对应的叶子节点 \(t\)、满足 \(fail[u]=t\) 的所有节点 \(u\)。

最后使用一遍 \(\texttt{dfs}\) 在 Trie 图上找环即可。

实现

  • 在插入模式串以及建立 \(fail\) 指针时利用 \(fail\) 的关系标记非法节点。
  • \(\texttt{dfs}\) 找环就是维护一个访问数组 \(vis[]\) 以及是否在栈中的数组 \(ins[]\),然后当遇到一个点在 \(\texttt{dfs}\) 树对应的栈中的时候就返回 \(true\) 即可。
// Problem: P2444 [POI2000]病毒
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2444
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
 
#define debug(x) cerr << #x << ": " << (x) << endl
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
#define all(x) (x).begin(), (x).end()
 
#define x first
#define y second
using pii = pair<int, int>;
using ll = long long;
 
inline void read(int &x){
    int s=0; x=1;
    char ch=getchar();
    while(ch<'0' || ch>'9') {if(ch=='-')x=-1;ch=getchar();}
    while(ch>='0' && ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    x*=s;
}

const int N=1e5+5;

int n;

int tr[N][2], idx;
int fail[N];
bool ng[N];

void insert(string &s){
	int u=0;
	for(auto &c: s){
		int val=c-'0';
		int &go=tr[u][val];
		if(!go) go=++idx;
		u=go;
	}
	ng[u]=true;
}

void build(){
	queue<int> q;
	rep(c,0,1) if(tr[0][c]){
		q.push(tr[0][c]);
		fail[tr[0][c]]=0;
	}
	
	while(q.size()){
		int u=q.front(); q.pop();
		rep(c,0,1){
			int &go=tr[u][c];
			if(!go) go=tr[fail[u]][c];
			else fail[go]=tr[fail[u]][c], ng[go]|=ng[fail[go]], q.push(go);
		}
	}
}

bool vis[N], ins[N];

bool dfs(int u){
	vis[u]=ins[u]=true;
	rep(c,0,1){
		int go=tr[u][c];
		if(ins[go]) return true;
		if(ng[go] || vis[go]) continue;
		if(dfs(go)) return true;
	}
	ins[u]=false;
	return false;
}

void solve(){
	puts(dfs(0)? "TAK": "NIE");
}

signed main(){
	cin>>n;
	rep(i,1,n){
		string s; cin>>s;
		insert(s);
	}	
	build();
	
	solve();
	
	return 0;
}

标签:ch,2938,int,tr,Poi2000,dfs,go,字符串,fail
来源: https://www.cnblogs.com/Tenshi/p/16644151.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有