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