1. 程式人生 > 其它 >AcWing 860. 染色法判定二分圖

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;
}