二分图的概念就是两一个图分为两个集合,每个集合内部不能互相连接,但是两个集合可以互相连接。两个集合假设我们分为1号集合以及2号集合,初始的时候任何点都没有染色(染色其实就是染1号点或者是2号)我们可以随便找一个点染成1号那么和它相邻(连接)的点就只能是2号,如此染色下去,我们采用dfs进去染色,若是碰到已经有染色了的点,就判断一下已经染的色是不是和将要染的色矛盾,如果矛盾就代表存在奇数环,代表不存在二分图。
而且可能因为有不连通的点所有我们要遍历所有的点都用dfs进行染色判断
#include<iostream>
#include<cstring>
using namespace std;
const int N=1e5+10,M=2*N;
int h[N],e[M],ne[M],idx;
int color[N];
int n,m;
void add(int a,int b)
{
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
bool dfs(int u,int c)
{
color[u]=c;//将u号点染色
for(int i=h[u];i!=-1;i=ne[i])//将它临接的点染色然后dfs下去,若dfs返回的是false就代表dfs下出问题了
{
int j=e[i];
if(!color[j])
{
if(!dfs(j,3-c))return false;
}
else//若已经染色过了,并且染的色和找到它的那个点的颜色一样那么就不是二分图返回false
{
if(color[j]==c)return false;
}
}
return true;
}
int main()
{
memset(h,-1,sizeof h);
cin>>n>>m;
while(m--)
{
int a,b;
cin>>a>>b;
add(a,b);
add(b,a);
}
bool flag=false;
for(int i=1;i<=n;i++)//遍历所有的点
{
if(!color[i])
{
if(!dfs(i,1))
{
flag=true;
break;
}
}
}
if(flag)cout<<"No"<<endl;
else cout<<"Yes"<<endl;
}