二分图的判断

1、题目描述

题目来自算法导论第3版22章的第7题,题目描述如下
  职业摔跤选手可以分为两种类型:“娃娃脸”(好人)型和“高跟鞋”(“坏人”)型。在任意一对职业摔跤选手之间都可能存在竞争关系。假定有nnn个职业摔跤手,并且有一个给出的竞争关系的rrr对摔跤手的链表。请给出一个时间复杂度为O(n+R)O(n+R)O(n+R)的算法来判断是否可以将某些型"娃娃脸",而剩下的划分为"高跟鞋"型,使得所有的竞争关系均只存在于娃娃脸型和高跟鞋型选手之间。如果可以进行这种划分,则算法该如何设计。

2、问题分析

  这个问题等价于判断一个图是不是二分图的问题,因为同类之间不可能有关系,而不同类之间可以存在关系。
  用到的定理:一个图是二分图当且仅当图中所有回路都为偶数个顶点。
  用到的方法:采用点着色的方法。

3、算法思路

  1. 初始化图G(V,E)G(V,E)G(V,E)顶点颜色为白色。
    时间:O(V)O(V)O(V)
  2. 初始队列QQQ为空,随机选择一个顶点sss加入队列QQQsss的颜色着为红色。
    时间:O(3)O(3)O(3)
  3. 执行如下循环,如果队列QQQ不为空,从队列中弹出元素赋值给顶点uuu,遍历uuu的邻接链表(也可以是邻接矩阵),若链表非空,对于顶点uuu中邻接矩阵的元素vvv,如果vvv的颜色是白色且uuu的颜色是红色,那么将顶点vvv着成蓝色;若vvv的颜色是白色且uuu的颜色是蓝色,那么将顶点vvv着成红色;若顶点uuu的颜色和顶点vvv的颜色相同,那么直接break,表示该图不是二分图。在着色的过程,将顶点vvv加入到队列QQQ中。执行循环直到队列空为止。
    时间: 队列出来元素O(V)O(V)O(V),邻接链表遍历O(2E)O(2E)O(2E),顶点颜色着色O(V)O(V)O(V),顶点入队列O(V)O(V)O(V)
  4. 最终即可返回是否为二分图的信息。
4、伪代码
Judge(G,s) {
	for each vertex u in V[G] - {s}
		do color[u] <- white
	color[s] <- red
	Q <- empty
	ENQUEUE(Q,S)
	while Q != empty
		do u <- DEQUEUE(Q)
			for each v in Adj[u]
				do if color[v] == white && color[u] == red
				   then color[v] <- blue
						ENQUEUE(Q,v)
				   else if color[v] == white && color[u] == blue
				   then color[v] <- red
						ENQUEUE(Q,v)
				   else if color[u] == color[v]
				   then break;  
				   
}

最终时间复杂度:O(V+E)O(V+E)O(V+E)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值