推荐博客:https://blog.youkuaiyun.com/c20180630/article/details/70175814
定义
二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。
无向图G为二分图的充分必要条件是,G至少有两个顶点,且其所有回路的长度均为偶数。
易知:任何无回路的的图均是二分图
判定
判断二分图的常见方法是染色法:
开始对任意一未染色的顶点染色,之后判断其相邻的顶点中,若未染色则将其染上和相邻顶点不同的颜色, 若已经染色且颜色和相邻顶点的颜色相同则说明不是二分图,若颜色不同则继续判断,当所有顶点都被染色,且没有发现同色的相邻顶点,就退出。
例题:uva10004
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
// 二分图的判定
const int N = 200+5;
int G[N][N], color[N], n,m;
bool dfs(int v, int c){
color[v] = c; //将当前顶点涂色
for(int i = 0; i < n; i++){ //遍历所有相邻顶点,即连着的点
if(G[v][i] == 1){ //如果顶点存在
if(color[i] == c) //如果颜色重复,就返回false
return false;
if(color[i] == 0 && !dfs(i,-c)) //如果还未涂色,就染上相反的颜色-c,并dfs这个顶点,进入下一层
return false; //返回false
}
}
return true; //如果所有顶点涂完色,并且没有出现同色的相邻顶点,就返回true
}
void solve(){
for(int i = 0; i < n; ++i){
if(color[i] == 0){
if(!dfs(i,1)){
printf("NOT BICOLORABLE.\n");
return;
}
}
}
printf("BICOLORABLE.\n");
}
int main()
{
freopen("in.txt","r",stdin);
while(scanf("%d",&n)==1&&n){
memset(color, 0, sizeof(color));
memset(G, 0, sizeof(G));
scanf("%d",&m);
for(int i = 0; i < m; i++){
int u,v;
scanf("%d %d",&u,&v);
//因为是无向图,所以要往两个方向添加边
G[u][v] = 1;
G[v][u] = 1;
}
solve();
}
return 0;
}