我们不能让重复过的字串出现在无限串上(就叫这个了。。。)

也就是要自动机一直能匹配但就是匹配不到,那么就是在自动机上找一个环。

dfs判环即可。注意是个有向图。

 #include<bits/stdc++.h>
using namespace std;
const int N=;
struct node
{
int v[],f,s;
}t[N];
int n,cnt;
queue<int>q;
char s[];
void build()
{
int l=strlen(s);int now=;
for(int i=;i<l;++i)
{
if(t[now].v[s[i]-'']){
now=t[now].v[s[i]-''];
}
else{
now=t[now].v[s[i]-'']=++cnt;
}
}
t[now].s++;
}
void getfail()
{
for(int i=;i<;++i)
{
if(t[].v[i])q.push(t[].v[i]),t[t[].v[i]].f=;
}
while(!q.empty())
{
int x=q.front();q.pop();
for(int i=;i<;++i)
{
if(t[x].v[i]){
q.push(t[x].v[i]);
t[t[x].v[i]].f=t[t[x].f].v[i];
t[t[x].v[i]].s|=t[t[t[x].v[i]].f].s;//我们不是统计个数而是坚决拒绝结束标记的存在
}
else{
t[x].v[i]=t[t[x].f].v[i];
}
}
}
}
bool in[N],v[N];
bool dfs(int x)
{
in[x]=;
for(int i=;i<;++i)
{
int y=t[x].v[i];
if(in[y])return ;
if(t[y].s||v[y])continue;
v[y]=;
if(dfs(y))return ;
}
in[x]=;return ;
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;++i)
{
scanf("%s",s);
build();
}
getfail();
if(dfs())puts("TAK");
else puts("NIE");
return ;
}
05-15 02:18