【问题标题】:Splitting people into two teams having the graph of relationships将人员分成两个具有关系图的团队
【发布时间】:2021-01-11 19:35:03
【问题描述】:

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

【问题讨论】:

  • 感觉好像少了点什么。因为这太琐碎了。只要把2个朋友放在一个队里,这个队里的每个人都是朋友,所以他们可以赢。
  • @yemre 好吧,实际上它比这更微不足道。空队获胜。一支只有一名球员的球队也是如此。所以甚至不需要找两个人是朋友^^
  • @Paul,是的,你是对的。我想我是想举一个更“自然”的例子。但当然,根据提问者的定义,只有一名或零名球员的球队也会获胜。
  • @yemre OP 没有提到它,但团队规模必须是 n/2 才能使问题有意义
  • 一个非常合理的结果是他的团队中有一个未连接的节点,并且该节点“赢得”了比赛......

标签: algorithm graph


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    基本上,您正在寻找cliques

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

    伪代码:

    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)
      }
    }
    

    【讨论】:

    • 反过来可能会更快:找到连接的组件,然后检查其中任何一个是否完全连接。
    • @tobias_k 你会如何定义这些连接的组件?
    • 只需进行深度优先搜索,您到达的所有节点都在一个组件中。检查是否所有节点都已连接(基本上只是所有节点的边数与组中的节点数减一一样多),然后继续图的其余部分。这种方式应该是 O(n)。
    • @tobias_k - 这是一个很好的观点。写一个答案
    猜你喜欢
    • 1970-01-01
    • 2015-01-23
    • 2018-05-01
    • 1970-01-01
    • 2019-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多