1. 程式人生 > >二分圖判斷

二分圖判斷

二分圖又稱為二部圖,其定義是:設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;
}