二分圖判斷
阿新 • • 發佈:2018-12-22
二分圖又稱為二部圖,其定義是:設G=(V,E)是一個無向圖。如頂點集V可分割為兩個互不相交的子集,並且圖中每條邊依附的兩個頂點都分屬兩個不同的子集。則稱圖G為二分圖。也就是說在二分圖中,頂點可以分為兩個集合X和Y,每一條邊的兩個頂點都分別位於X和Y集合中。它滿足這樣一個特性,即有兩頂點集且圖中每條邊的的兩個頂點分別位於兩個頂點集中,每個頂點集中沒有邊相連線!如下圖所示:
無向圖G為二分圖的充分必要條件是,G至少有兩個頂點,且其所有迴路的長度均為偶數。
這是一個二分圖,所有相鄰頂點顏色不同(使用顏色區分只是為了好表達)。這不是一個二分圖,存在相鄰頂點顏色相同的情況,且我們發現它的迴路長度為奇數。因此,可以推出如果一個圖存在奇圈(長度為奇數的迴路),則它一定不是二分圖。
判定一個圖是否是二分圖比較簡單,可以使用 BFS解決。演算法過程為:藉助佇列,進行寬度優先遍歷,先對一個起點著色RED,然後將其所有相鄰的節點著色為BLUE,並加入佇列。只要能保證相鄰的節點是不同的顏色即可。
以上轉自:https://blog.csdn.net/serena_0916/article/details/53560888?utm_source=copy
下面來一份我的程式碼:
#include<iostream> #include<cstdio> #include<vector> #include<queue> #include<cstring> using namespace std; #define MAX_N 10000 vector<int> g[MAX_N]; int color[MAX_N]; int bfs_check(int x){//判斷是否為二分圖 queue<int> q; q.push(x); color[x] = 1; while(!q.empty()){ int from = q.front(); q.pop(); int sz = g[from].size(); for(int i = 0; i < sz; i++){ if(color[g[from][i]] == -1){ q.push(g[from][i]); color[g[from][i]] = !color[from];//相鄰的點染成不同顏色 } if(color[g[from][i]] == color[from]){//相鄰的點顏色相同 return 0;//不是 } } } return 1;//是 } int main(){ memset(color,-1,sizeof color); int n, m; cin >> n >> m; for(int i = 0; i < m; i++){ int a,b,c; scanf("%d%d",&a,&b); g[a].push_back(b); g[b].push_back(a); } if(bfs_check(1)) cout << "Yes" << endl; else{ cout << "No" << endl; } return 0; }