Title

AcWing 860. 染色法判定二分图

AcWing 860. 染色法判定二分图

860. 染色法判定二分图
给定一个 n 个点 m 条边的无向图,图中可能存在重边和自环。
请你判断这个图是否是二分图。

  • 二分图里面可能存在多个联通块
  • 二分图:把点分成两个集合,且线段上的两点比分属于两个不同的集合(阵营),当出现第三个集合(阵营时),该图不是二分图。
  • 比如某个世界存在两个忍屯,忍者小a属于忍屯A,忍者小b属于忍屯B,小a和小b之间有一条皇帝的线来牵着,表示他们是不同屯的。有一天,发现有一个忍者小c和忍者小a、小b都各自有一条线牵着,经过推断,小c是属于第三个屯,可得这个世界中的地图也并不是只有两个屯的图。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
int color[N];

int h[N],e[N*2],ne[N*2],idx=0;
void add(int a,int b)
{
	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
int n,m;


bool BFS_biparts(int u)
{
	queue<int > q;
	q.push(u);
	color[u]=1;
	while(q.size())
	{
		int t = q.front();
		q.pop();
		for(int i = h[t];~i;i=ne[i])
		{
			int j=e[i];
		    if(!color[j])
		    {
		    	color[j]=3-color[t];//用1和2来表示不同的颜色,也可以用0和1,其中可以用~来实现转换 
		    	q.push(j);
			}
			else
				if(color[j]+color[t]!=3)
				   return false;
		}    
	}
	return true;
}
int main()
{
	cin>>n>>m;
	memset(h,-1,sizeof(h));
	memset(color,0,sizeof(color));
	for(int i=0;i<m;i++)
	{
		int a,b;
		cin>>a>>b;
		add(a,b);add(b,a);
	}
	int flag=1;
	for(int i=1;i<n;i++)//搜遍每一个联通块 
	{
		if(color[i]==0)
		{
			if(!BFS_biparts(i))
			{
				flag=0;
				break;
			}
		}
	}
	
	if(flag)cout<<"Yes";
	else cout<<"No";
	return 0;
}

posted @ 2021-07-21 16:47  BeautifulWater  阅读(65)  评论(0编辑  收藏  举报