【算法描述】
二分图又称作二部图,是图论中的一种特殊模型。 设G=(V, E)是一个无向连通图,如果顶点集V可分割为两个互不相交的子集A、B,并且边集E中的每条边(i, j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A, j in B),则称无向连通图G为一个二分图。
黑白染色法判断无向连通图是二分图的大致思路就是先找到一个没被染色的节点u,把它染上一种颜色,之后遍历所有与它相连的节点v,如果节点v已被染色并且颜色和节点u一样,那么就失败了。如果这个节点v没有被染色,先把它染成与节点u不同颜色的颜色,然后遍历所有与节点v相连的节点......。就这样循环下去,直到结束为止。
注意:若图G是非连通图,则需要依次判断各连通子图是不是二分图。
【程序代码】
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5;
vector<int> G[maxn];
int color[maxn];
int bfs(int u) {
queue<int> Q;
Q.push(u);
color[u]=1;
while(!Q.empty()) {
int t=Q.front();
Q.pop();
for(int i=0; i<G[t].size(); i++) {
if(color[G[t][i]]==color[t])
return 0; //Adjacent nodes are the same color, not bipartite graph
else if(color[G[t][i]]==0) { //no dyeing
color[G[t][i]]=-color[t];
Q.push(G[t][i]);
}
}
}
return 1;
}
int main() {
int n,m,x,y;
cin>>n>>m;
for(int i=0; i<n; i++) { //init
G[i].clear();
color[i]=0;
}
for(int i=0; i<m; i++) { //Adjacency List
cin>>x>>y;
G[x].push_back(y);
G[y].push_back(x);
}
if(bfs(1))
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
return 0;
}
【测试数据】
in1:
9 8
1 6
2 6
2 7
3 8
3 9
4 7
5 6
5 9
out1:
YES
----------
in2:
9 8
1 6
2 6
2 7
3 8
3 9
4 7
5 6
6 7
out2:
NO
【参考文献】
https://baike.baidu.com/item/%E4%BA%8C%E5%88%86%E5%9B%BE/9089095?fr=aladdin
https://www.cnblogs.com/jsawz/p/6847185.html
https://blog.csdn.net/qq_43469254/article/details/88956159
https://blog.csdn.net/chaiwenjun000/article/details/47662911
https://blog.csdn.net/l2533636371/article/details/79749020
https://blog.csdn.net/FeBr2/article/details/51932611