[HDU5215]Cycle

Posted by Dispwnl on October 8, 2018

题目

题目大意

多组数据

给定一个无向图,问是否存在奇环/偶环

Sample Input

3
1 0
3 3
1 2
2 3
3 1
4 4
1 2
2 3
3 4
4 1

Sample Output

NO
NO
YES
NO
NO
YES

题解

判断奇环,只要判断这个图是否是一个二分图即可

判断偶环,建立$dfs$树的时候,如果遇到返祖边,两个点之间的边数为奇数说明存在偶环

但是还可能有两个奇环拼成一个偶环的情况,如图:

发现如果返祖边到的点在某个奇环之内,ta也存在偶环

所以每次找到返祖边都把两点之间的点标记一下判断即可

代码

# include<bits/stdc++.h>
using namespace std;
const int MAX=3e5+5;
struct p{
	int x,y;
}c[MAX<<1];
int n,m,num;
int h[MAX],f[MAX],d[MAX],col[MAX];
bool fl,fl1;
bool _col[MAX];
int read()
{
	int x(0);
	char ch=getchar();
	for(;!isdigit(ch);ch=getchar());
	for(;isdigit(ch);x=x*10+ch-48,ch=getchar());
	return x;
}
void add()
{
	int x=read(),y=read();
	c[++num]=(p){h[x],y},h[x]=num;
	c[++num]=(p){h[y],x},h[y]=num;
}
void dfs(int x,int fa=0)
{
	d[x]=d[fa]+1,col[x]=col[fa]^1,f[x]=fa;
	for(int i=h[x];i;i=c[i].x)
	  if(c[i].y!=fa)
	  {
		if(col[c[i].y]!=-1)
	  	{
	  		if(col[c[i].y]==col[x])
	  		{
	  			fl1=1;
	  			for(int l=x;l!=c[i].y&&l;l=f[l])
	  			  {
	  			  	if(_col[l]) fl=1;
	  			  	_col[l]=1;
	  			  	if(fl) break;
				  }
			}
			else fl=1;
		}
		else dfs(c[i].y,x);
		if(fl&&fl1) break;
	  }
}
int main()
{
	int T=read();
	do{
		n=read(),m=read();
		memset(h,0,sizeof(h));
		memset(_col,0,sizeof(_col));
		memset(col,-1,sizeof(col));
		memset(d,0,sizeof(d));
		num=fl=fl1=col[0]=0;
		for(int i=1;i<=m;++i,add());
		for(int i=1;i<=n;++i)
		  if(col[i]==-1) dfs(i);
		fl1?printf("YES\n"):printf("NO\n");
		fl?printf("YES\n"):printf("NO\n");
	}while(--T);
	return 0;
}