【算法描述】
二分圖又稱作二部圖,是圖論中的一種特殊模型。 設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