如何判断一个图是否是二分图

问题描述:给定一个无向图G=<V,E>,如何能够在O(V+E)时间内判断这个图是否是一个二分图(或者称为2着色)

分析:如果这个无向图没有回路,那么它一定是可以二分的,我们直接就可以利用BFS来为二分图着色(根据当前节点的颜色,对其所有相邻节点涂另一个颜色)。
     如果这个无向图有回路,如果回路的边数是偶偶数,那么它还是二分的,如果是奇数,那么它就不是二分的。如何判断回路的边数是奇数还是偶数呢?
    方法1:利用DFS记录初始节点到每个节点的距离d[],初始节点为s,假设当前访问节点为v,如图:
如何判断一个图是否是二分的? - kevinlee_2010 - 云淡风轻
 c是从v到s和从u道s的交叉点,c当然可以和s相同,如果当前节点v相邻的节点u已经被标记为灰色(即正在栈中、或递归调用还没返回),那么这个图就是存在环路的,如何判断当前环路的边是否是奇数呢,不是一般性,假设d2>d3,那么我们只需要判断d2-d3+1是否为奇数,如果是奇数,则return false,证明当前图不是二分,如果是偶数则继续遍历,直到所有点均已遍历完毕,则返回true。
d2-d3正是从v到c和从u到c距离的差值,环c->....->v->u->...->c的变长可以表示为N=2*d3+d2-d3+1,所以N的奇偶性完全由d2-d3+1决定。当然在DFS遍历的时候也可能出现如下情形:
如何判断一个图是否是二分的? - kevinlee_2010 - 云淡风轻
当前访问的节点v,与它相邻的节点u已经是灰色,那么按照刚才的分析,color[u]="Gray",但中不一定构成回路,但我们的判断d2-d1+1依然正确,因为这种情况下d2-d1+1=2,一定是偶数
时间代价O(V+E),空间O(1)(不考虑本身图所占用的结构开销)
 
方法2:我们还可以利用类似减枝的方法来判断图中的回路是否为偶数,基本思想是这样的,如果一个无向图中存在环路,那么在这个环路中每个节点的度数>=2,。
1,首先,我们需要统计每个节点的度数,记录在degree[n]中 O(V+E)
        2,删除所有度数<=1的节点(删除操作就是将该节点对应的边删除,并将对应的顶点的度数-1),然后将所有更新后的顶点度数为1的点加入队列当中。O(V)
       3,然后对队列中的每个元素重复步骤1,最后如果还有没有被删除的节点(即还存在度数>=2的节点),证明图中存在回路。如果全部都已删除则图中不存在回路,即图是二分的
        4,(上面的过程看做预处理过程)如果存在回路,接下来,对剩下的每一个节点,统计从这个节点开始的所有回路(即用DFS从这一点开始,又回到这一点的所有回路),并记录其路径的长度,并标记被访问的状态,如果存在偶数边则return false。
        5,如果存在还没有被访问的点(另一个连通分支的回路),继续步骤4,知道所有节点都被访问完毕,return true.
方法2的复杂度要高一些,应该有一些可以优化的地方。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值