G - Return to 1 Editorial by TOMWT

dfs*2

If there is no cycle containing \(1\),No.

Let \(ans\) be GCD of length of all cycles containing \(1\).

If \(ans|10^{10^{100}}\) meets, surely we have at least one way to move \(10^{10^{100}}\) times to get back, according to Bézout’s lemma, we have at least one way to arrange how many times we should go around one cycle.

It’s known that \(ans\leq n\), so \(ans|10^{18}\Leftrightarrow ans|10^{10^{100}}\).

In fact we don’t need to find all cycles. The method below is one choice.

#include<stdio.h>
#include<vector>
#define N 200009
#define abs(x) ((x)>>31?-(x):(x))
using namespace std;
inline char nc()
{
	static char buf[99999],*l,*r;
	return l==r&&(r=(l=buf)+fread(buf,1,99999,stdin),l==r)?EOF:*l++;
}
inline void read(int&x)
{
	char c=nc();for(;c<'0'||'9'<c;c=nc());
	for(x=0;'0'<=c&&c<='9';x=(x<<3)+(x<<1)+(c^48),c=nc());
}
int t,n,m,len,dis[N];vector<int>e1[N],e2[N];bool v[N],ans;
struct __readt__{inline __readt__(){read(t);}}_readt___;
inline int gcd(const int&x,const int&y){if(y)return gcd(y,x%y);return x;}
inline void dfs(const int&i)
{
	if(!i)if(dis[i])len=dis[i];
	for(int j=0;j<e2[i].size();++j)if(!v[e2[i][j]])
		v[e2[i][j]]=1,dis[e2[i][j]]=dis[i]+1,dfs(e2[i][j]);
}
inline void dfs2(const int&i,const int&d)
{
	if(!v[i])return;
	if(~dis[i])
	{
		if(!(1000000000000000000ll%gcd(len,abs(d-dis[i]))))ans=1;
		return;
	}
	dis[i]=d;
	for(int j=0;j<e1[i].size()&&!ans;++j)dfs2(e1[i][j],d+1);
}
main()
{
	read(n);read(m);
	for(int i=0;i<n;v[i]=dis[i]=0,e1[i].clear(),e2[i++].clear());
	for(int u,v;m--;)read(u),read(v),--u,--v,
		e1[u].emplace_back(v),e2[v].emplace_back(u);
	dis[0]=0;dfs(0);ans=0;
	if(!v[0]){printf("No\n");goto nxt;}
	if(!(1000000000000000000ll%len)){printf("Yes\n");goto nxt;}
	for(int i=0;i<n;dis[i++]=-1);
	dfs2(0,0);
	printf(ans?"Yes\n":"No\n");
	nxt:if(--t)main();
}

posted:
last update: