bzoj4179: B

传送门: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\n",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\n",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;
}


posted @ 2015-07-26 15:01  orzpps  阅读(148)  评论(0编辑  收藏  举报