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

来源:互联网 发布:新开淘宝网店推广方法 编辑:程序博客网 时间:2024/04/30 03:20

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

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

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

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

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

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

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

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

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