当前位置:   article > 正文

无向图G=(V,E)的二分图判断

g=(v,e)

二分图的概念

无向图 G = ( V , E ) G=(V,E) G=(V,E)的顶点集 V V V可分为两个集合 V 1 V_1 V1 V 2 V_2 V2   s . t .   ∀ ( u , v ) ∈ E ,   ∃   u ∈ V 1 , v ∈ V 2 \: s.t. \: \forall (u,v) \in E, \: \exists \: u\in V_1,v \in V_2 s.t.(u,v)E,uV1,vV2 u ∈ V 2 , v ∈ V 1 u\in V_2,v \in V_1 uV2,vV1,则称图 G G G为二分图,即所有的边都位于 V 1 V_1 V1 V 2 V_2 V2之间。

判断方法

判断二分图的常用方法为染色法。通过遍历整个无向图 G G G,对图中的顶点进行有规律的染色。

染色步骤为:选择一个起始顶点 u u u,将其染成黑色 B L A C K BLACK BLACK;然后遍历所有与 u u u相邻的顶点 v v v,将 v v v染成白色 W H I T E WHITE WHITE;同时再将与顶点 v v v相邻的顶点 w w w,将 w w w染成黑色 B L A C K BLACK BLACK;依次进行下去,直到遍历结束。

若图中还有顶点未遍历,则重复上述染色步骤。

如果我们能够完成染色步骤,那么该无向图为二分图。

如果染色过程中产生了冲突,即当遍历到某个顶点 x x x时,该顶点已经染色,并且 x x x的颜色与我们准备给其染成的颜色不一致,则表示该无向图不是二分图。

判断二分图的过程

可以使用深度优先搜索或广度优先搜索对无向图进行遍历。

考虑到无向图可能是一个非连通图,因此需要多次执行广度优先搜索或深度优先搜索才能完全遍历所有的顶点。

BFS Pseudocode

G = ( V , E ) G=(V,E) G=(V,E)

∀ \forall 顶点 u ∈ V u\in V uV,定义 v i s i t e d [ u ] visited[u] visited[u]存储搜索过程中顶点 u u u的染色情况:

U N V I S I T E D UNVISITED UNVISITED:未访问状态。
W H I T E WHITE WHITE:标记为白色。
B L A C K BLACK BLACK:标记为黑色。

定义First-in, first-out (FIFO)队列 Q Q Q,存放搜索中的顶点。

BFS-Pseudocode(G)
	// 初始化顶点的颜色
	for every u in V[G]
		visited[u] = UNVISITED

	//初始化队列
	Q = nil

	// 遍历无向图的全部顶点,进行染色
	for every u in V[G]
		if visited[u] == UNVISITED then
			result = BFS(u)
			do if result == false then
				return false
	return true
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
BFS(u)
	// 开始搜索时设置源顶点u的颜色为BLACK,并放入队列中
	Q.push(u)
	visited[u] = BLACK
	// Q队列存放搜索中的顶点;该顶点已被染色,但其邻接表的顶点还尚未被染色
	while Q  is not empty
		do u = Q.pop()
		for v in Adj[u] // 顶点u的邻接表
			do if  visited[v] == UNVISITED then // 对未访问的顶点染成与u相反的颜色
				visited[v] = visited[u] == WHITE ? BLACK: WHITE
				Q.push(v)
			else if visited[u] == visited[v] then // 染色过程中产生了冲突
				return false // 不是二分图
			else then
				trivial
	return true
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

DFS Pseudocode

DFS-Pseudocode(G)
	// 初始化顶点的颜色
	for every u in V[G]
		visited[u] = UNVISITED

	// 判断结果
	result = true

	// 遍历无向图的全部顶点,进行染色
	for every u in V[G]
		if visited[u] == UNVISITED then
			DFS(u, BLACK)
			do if result == false then
				return false
	return true
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
DFS(u, color)
	// 顶点u的染色为color
	visited[u] = color
	for v in Adj[u] // 顶点u的邻接表
		do if  visited[v] == UNVISITED then
			// 对未访问的顶点染成与u相反的颜色
			reverseColor = color == WHITE ? BLACK: WHITE
			DFS(v, reverseColor)
			do if result == flase then // 深度遍历过程中,提前判断,提前结束
				return
		else if color == visited[v] then // 染色过程中产生了冲突
			result = false // 不是二分图
			return
		else then
			trivial
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/152063
推荐阅读
相关标签
  

闽ICP备14008679号