传送门:http://www.lydsy.com:808/JudgeOnline/problem.php?id=4179
思路:这题和上一题不是差不多吗....就是在没有环的时候找一个最长路,长度超过L就能完成任务。
#include<cstdio> #include<cstring> #include<algorithm> const int maxn=1048580,maxq=1048580; using namespace std; int n,L;char s[maxn]; struct AC_DFA{ int tot,ch[maxn][2],fail[maxn],q[maxq+10],head,tail,dis[maxn];bool dang[maxn],bo[maxn],ins[maxn]; int tra(char t){return t=='A'?0:1;} void clear(){tot=0;memset(ch,0,sizeof(ch)),memset(dis,0,sizeof(dis)),memset(dang,0,sizeof(dang)*3);} void insert(){ int p=0; for (int i=0;i<(int)strlen(s);p=ch[p][tra(s[i])],i++) if (!ch[p][tra(s[i])]) ch[p][tra(s[i])]=++tot; dang[p]=1; } void getfail(){ head=0,q[tail=1]=0,fail[0]=-1; while (head!=tail){ //printf("%d %d ",fail[q[head]],fail[q[tail]]); int x=q[++head]; for (int i=0;i<=1;i++) if (ch[x][i]) q[++tail]=ch[x][i],fail[ch[x][i]]=x==0?0:ch[fail[x]][i],dang[ch[x][i]]|=dang[fail[ch[x][i]]]; else ch[x][i]=x==0?0:ch[fail[x]][i]; } } bool dfs(int x){ ins[x]=1; for (int i=0;i<=1;i++){ int v=ch[x][i]; if (ins[v]) return 1; if (bo[v]||dang[v]) continue; bo[v]=1; if (dfs(v)) return 1; } ins[x]=0;return 0; } void find(){ head=0,q[tail=1]=0,dis[0]=0,bo[0]=1,memset(bo,0,sizeof(bo)); while (head!=tail){ if (++head>maxq) head=1; int x=q[head]; for (int i=0;i<=1;i++){ int v=ch[x][i]; if (dang[v]) continue; if (dis[v]<dis[x]+1){ dis[v]=dis[x]+1; if (!bo[v]){ if (++tail>maxq) tail=1; q[tail]=v,bo[v]=1; } } } bo[x]=0; } int maxs=0; for (int i=0;i<=tot;i++) maxs=max(maxs,dis[i]); //printf("%d ",maxs); puts(maxs>=L?"Yes":"No"); } }T; int main(){ while (scanf("%d%d",&n,&L)!=EOF){T.clear(); for (int i=1;i<=n;i++) scanf("%s",s),T.insert(); T.getfail();if (T.dfs(0)){puts("Yes");continue;} T.find(); } return 0; }