定义
二分图(中文翻译问题,有时也称作二部图),是图论中的一种特殊模型。 如果图可以分为两部分: 绿色和蓝色,并且每一条连线都连接着一个绿色顶点和一个蓝色定点,则称这个图为一个二分图.下图就是一个二分图.
二分图检测
示例图,如下: 肉眼很难区分出两部分,需要采用一定的算法才可区分,下面就介绍检测的方法--染色.
染色
首先,选择一个节点,置为蓝色(绿色也可),再将与之连线的节点置为对立的颜色-绿色,按深度优先(广度优先也可)的逻辑,将节点依次置为对立色,如果最终结果为:每条边都连接这一个蓝色和一个绿色节点,则二分图检测成功.
代码实现(java)
import java.util.ArrayList;
public class BipartitionDetection {
/**
* 图的类
* public class Graph {
* private int V; // 顶点
* private TreeSet<Integer>[] adj; // 每个顶点相连的顶点树数组
* }
*/
private Graph G;
/**
* 已访问的顶点数组
*/
private boolean[] visited;
/**
* 0->蓝色, 1->绿色
*/
private int[] colors;
/**
* 是否为二分图
*/
private boolean isBipartite = true;
public BipartitionDetection(Graph G) {
this.G = G;
visited = new boolean[G.V()];
colors = new int[G.V()];
for (int i = 0; i < G.V(); i++)
// 初始化
colors[i] = -1;
for (int v = 0; v < G.V(); v++)
if (!visited[v])
if (!dfs(v, 0)) {
isBipartite = false;
break;
}
}
/**
* 递归遍历节点
*
* @param v 顶点
* @param color 颜色,0->蓝色, 1->绿色
*/
private boolean dfs(int v, int color) {
visited[v] = true;
colors[v] = color;
// 遍历与v相连的每一个顶点
for (int w : G.adj(v))
// 判断是否遍历过/染过色
if (!visited[w]) {
// 染为与v对立的颜色
if (!dfs(w, 1 - color)) return false;
} else if (colors[w] == colors[v]) {
// 已染色,判断与v相连的顶点颜色是否与v相同,若相同,则不满足二分图
return false;
}
return true;
}
/**
* 是否为二分图
*/
public boolean isBipartite() {
return isBipartite;
}
}
来源:oschina
链接:https://my.oschina.net/HaverLee/blog/3137396