Algorithm 将人员分成两个具有关系图的团队

Algorithm 将人员分成两个具有关系图的团队,algorithm,graph,Algorithm,Graph,我们有n玩家,其中一些玩家是朋友(如果约翰是萨拉的朋友,那么萨拉也是约翰的朋友)。我们想把这些球员分成两个队(一个队也可以是空的!)。如果一队中的所有球员都是朋友,而另一队中的每个球员都是球员的敌人(而不是朋友),那么该队就可以赢得比赛。给定一个带有n顶点和m边(每条边都表示友谊)的图,我如何检查我们是否可以拆分顶点以获得一个获胜的团队?基本上,您正在寻找 我们的获胜团队必须是原始图表中的一个小团体(他们都是彼此的朋友)。一旦找到一个群组,您需要检查该群组是否未连接到图的其余部分 Psudo代码

我们有
n
玩家,其中一些玩家是朋友(如果约翰是萨拉的朋友,那么萨拉也是约翰的朋友)。我们想把这些球员分成两个队(一个队也可以是空的!)。如果一队中的所有球员都是朋友,而另一队中的每个球员都是球员的敌人(而不是朋友),那么该队就可以赢得比赛。给定一个带有
n
顶点和
m
边(每条边都表示友谊)的图,我如何检查我们是否可以拆分顶点以获得一个获胜的团队?

基本上,您正在寻找

我们的获胜团队必须是原始图表中的一个小团体(他们都是彼此的朋友)。一旦找到一个群组,您需要检查该群组是否未连接到图的其余部分

Psudo代码:

allCliques = getAllCiques(originalGraph)
for each clique of allCliques {
  foundOutsideConnection = false
  for each node of clique {
    if (node is connected to any node outside the clique) {
      foundOutsideConnection = true
    }
  }
  if not foundOutsideConnection {
    print(clique)
  }
}

您正在查找图中的以下部分:(a)每个节点都连接到另一个节点,并且(b)没有节点连接到该部分之外的节点。最简单和最快的方法应该是扭转这两个步骤,即找到图中连接的组件,然后查看这些组件是否完全连接。第一部分是一个简单的深度优先搜索,第二部分只需计算边数

  • 从图中获取尚未成为组件一部分的任何节点
  • 从该节点执行深度优先搜索,以查找该节点所属组件中的所有节点
  • 检查组件是否完全连接,即组件中的每个节点都有一条到其他节点的边,即每个节点都有
    k-1
    边,总共有
    k(k-1)/2条
    边,
    k
    是组件的大小;如果是这样,则此组件是“获胜团队”
  • 如果还有未访问的节点,请继续执行步骤(1)

  • 总的复杂度应该是
    O(n)
    n
    是图中的节点数。

    感觉好像缺少了什么。因为这太琐碎了。只要把两个朋友放在一个队里,那么这个队的每个人都是朋友,所以他们可以赢。@yemre好吧,事实上这比这更微不足道。空队获胜了。一支只有一名球员的球队也是如此。所以甚至不需要找两个朋友保罗,是的,你是对的。我想我是想举一个更“自然”的例子。当然,根据询问者的定义,只有一名或零名玩家的团队也会获胜。@yemre OP没有提到这一点,但团队规模必须为
    n/2
    ,才能让问题变得有意义。一个非常合理的结果是,团队中有一个非连接节点,该节点“获胜”游戏…可能会更快:找到连接的组件,然后检查其中是否有完全连接的组件。@tobias_k如何定义这些连接的组件?只需进行深度优先搜索,所有到达的节点都在一个组件中。检查是否所有节点都已连接(基本上,只要所有节点的边数与组中节点的边数减1相同),然后继续处理图的其余部分。这样应该是O(n)@tobias_k-这是一个很好的观点。写一个答案