https://www.luogu.org/problemnew/show/P2444

有点恶心,不太明白fail的意义。

#include<bits/stdc++.h>
using namespace std;
#define ll long long struct Trie{
int nex[][],fail[],End[];
int root,L;
int newnode(){
/*for(int i=0;i<26;i++)
nex[L][i]=-1;*/
End[L++]=;
return L-;
} int cnt;
void init(){
L=;
cnt=;
memset(nex,-,sizeof(nex));
root=newnode();
} void insert(char buf[]){
int len=strlen(buf);
int now=root;
for(int i=;i<len;i++){
int &t=nex[now][buf[i]-''];
if(t==-)
t=newnode();
now=t;
}
End[now]++;
cnt++;
} void build(){
queue<int>Q;
fail[root]=root;
for(int i=;i<;i++){
if(nex[root][i]==-){
nex[root][i]=root;
//根节点没有对应的分支,还是必须回到根节点开始匹配
}
else{
//根节点的后继失配,先假定回到根节点匹配
fail[nex[root][i]]=root;
Q.push(nex[root][i]);
}
}
while(!Q.empty()){
int now=Q.front();
Q.pop();
for(int i=;i<;i++)
if(nex[now][i]==-){
//某个节点没有这个对应的分支,它失配了,沿着失配边去到最近的有这个分支的边?
nex[now][i]=nex[fail[now]][i];
}
else{
fail[nex[now][i]]=nex[fail[now]][i];
Q.push(nex[now][i]);
//如果这个节点的fail指针指向的点是End,那么因为这个节点蕴含他的fail节点,所以他也是End
End[now]|=End[fail[now]];
}
}
} /*int query(char buf[]){
int len=strlen(buf);
int now=root;
int res=0;
for(int i=0;i<len;i++){
now=nex[now][buf[i]-'0'];
int temp=now;
while(temp!=root&&End[temp]!=-1){
res+=End[temp];
End[temp]=-1;
temp=fail[temp];
}
//if(res==cnt)
//return res;
}
return res;
}*/ int vis[];
int instack[];
int find_circle(){
memset(vis,,sizeof(vis));
memset(vis,,sizeof(instack));
return dfs(root);
} int dfs(int id){
instack[id]=;
vis[id]=;
for(int i=;i<;i++){
if(instack[nex[id][i]]){
//该节点的下一条边在dfs栈中,是反向边
printf("TAK\n");
exit();
}
if(vis[nex[id][i]]==){
//不访问已经到过的表亲,表亲不可能成环
if(End[nex[id][i]]==){
//下一个点不是病毒
dfs(nex[id][i]);
}
}
}
instack[id]=;
return ;
} }; char buf[]; Trie ac; int n;
void solve(){
while(~scanf("%d",&n)){
if(n==)
break;
ac.init(); for(int i=;i<n;i++){
scanf("%s",buf);
ac.insert(buf);
}
ac.build();
//scanf("%s",buf); if(ac.find_circle()==){
cout<<"NIE"<<endl;
}
}
} int main(){
#ifdef Yinku
freopen("Yinku.in","r",stdin);
//freopen("Yinku.out","w",stdout);
#endif // Yinku
solve();
}

最新文章

  1. 批处理定时重启print打印服务,解决打印机异常队列堆积
  2. 快速入门系列--NOSQL--07MongoDB
  3. 从零开始一个iOS项目(一)——基本准备以及cocopods的安装
  4. Gym 100851K
  5. JAVA项目JDK版本修改
  6. CSS2系列:外边距合并问题(margincollapse)
  7. 租房时代,K2 BPM软件带你拥抱更好生活
  8. PHP header() 函数详细说明(301、404等错误设置)
  9. 15个Linux Yum命令实例--安装/卸载/更新
  10. PowerDesigner 的7种建模文件
  11. linux关闭防火墙及selinux
  12. Android 6.0 以及HttpClient
  13. linux cmd: netstat
  14. Swift中自定义打印方法
  15. Robot framework(RF) 用户关键字
  16. 卷积神经网络CNN的原理(二)---公式推导
  17. the principle of redbalck tree
  18. k8s学习笔记之二:使用kubeadm安装k8s集群
  19. 纯小白入手 vue3.0 CLI - 3.1 - 路由 ( router )
  20. javascript篇-typeof,instanceof,constructor,toString判断数据类型的用法和区别

热门文章

  1. 【Nutch基础教程之七】Nutch的2种执行模式:local及deploy
  2. 浅析怎样学好C语言
  3. Effective C++ 条款九、十 绝不在构造和析构过程中调用virtual函数|令operator=返回一个reference to *this
  4. centos6.3升级python至2.7.5
  5. JSP与HTML的差别
  6. GDI泄露+改EXE名
  7. python day - 8 文件
  8. sessionFactory的创建和四种查询方式
  9. ZeroMQ 初步认识
  10. linunx 下载文件到本地