算法导论22.2-6:好选手、坏选手问题

本文介绍了一种在O(n+r)时间内确定是否可以将摔跤手分为好选手和坏选手两类的方法,使得每场比赛都在一好一坏选手间进行。这等价于判断一个图是否为二分图的问题。文章提供了两种判断方法:一是通过深度优先搜索检查是否存在奇数个顶点的回路;二是通过删除度数小于等于1的节点来检查图中是否存在回路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Q:有两种类型的职业摔跤选手:一种是好“选手”,一种是坏“选手”。对于任意一对摔跤职业选手来说,他们中可能有,也可能没有比赛。假定有n位摔跤职业选手,并且有一份清单,上面列出了r对参加比赛的摔跤手。试给出一个o(n+r)时间的算法,它能否确定是否指定某些摔跤手为好选手,而将余下的摔跤手指定为坏选手,从而使得每一场比赛都是在一个好选手与一个坏选手之间进行。如果有可能做出这样的指定,你的算法就应该将它产生出来。

一、等价于判断图是否为二分图(二着色)的问题

二分图,就是顶点集V可分割为两个互不相交的子集,并且图中每条边依附的两个节点都分属于这两个互不相交的子集。如下图所示:

二、判断这个图是不是二分图

将好选手归为一类,坏选手归为一类。

若是某个图为二分图的话,当且仅当图中所有的回路都为偶数个顶点,顶点个数至少为2。因此,判断图中是否存在有奇数个顶点的回路即可。判断方法:

1、深度(或广度)优先搜寻中,若两个灰色节点有边连接,且二者的深度(到根节点的距离)之和为偶数,则表明存在有奇数个顶点的回路,即该图不是二分图。

2、如果该图没有回路,那一定是可以二分的;若有回路,则回路中节点的度数一定 >=2。

统计每个节点的度数;
删除所有度数<1的节点(将该节点对应的边删除,并将对应的顶点的度数-1);
然后将更新后的顶点度数为1的所有点加入队列当中,对队列中的每个元素重复上一步,即删除度数为1的点。最后如果还有没有被删除的节点(即还存在度数>=2的节点),证明图中存在回路。如果全部都已删除则图中不存在回路,即图是二分的;
如果存在回路,对剩下的每一个节点,统计从这个节点开始的所有回路(DFS),并记录路径的长度,标记访问状态,如果存在奇数边回路就表明不是二分图。否则,运行直到所有节点都被访问完毕。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值