【问题标题】:Divide a graph into two sets将一个图分成两组
【发布时间】:2015-11-10 07:21:18
【问题描述】:

问题来自Code jam

问题:
有没有办法将图的节点分成两组,使得不能留在同一组中的任何两个节点都应该在不同的组中。
有什么标准算法吗?

当每个组应该有相同的元素时,我应该如何解决这个问题。

【问题讨论】:

    标签: algorithm data-structures graph


    【解决方案1】:

    您从给定节点构建一个图(使用哈希表将名称映射到节点),然后使用 BFS 或 DFS 遍历该图并确定它是否是二分的(即,分成两个不相交的集合,使得一组中的节点仅与另一组中的节点处于“麻烦”状态,但与自己集中的任何节点无关)。这是通过为 BFS/DFS 访问的每个节点分配一个布尔值来完成的,然后检查其访问的任何邻居是否具有相同的值,这意味着该图不是二分图(不能分成两组)。

    【讨论】:

    • 为什么它被否决了?我看到它没有回答问题的第二部分,但对于第一部分来说绝对没问题,所以我认为这个答案“没有用”。
    • @amit 我没有投反对票(实际上我在您发表评论后投了赞成票),但是在仔细阅读了两个答案之后,我有点后悔。距离第二部分还有很长的路要走。当然,我宁愿只对你的答案投赞成票,而不是对这个答案投反对票。
    • 它可能被给出第一个答案的人投了反对票(我猜现在已经删除了),我投了反对票,因为它说你必须找出图表是否有周期(这是错误的 - 二分图可以有偶数长度的循环)
    【解决方案2】:

    首先,可行性问题(有没有这样的集合/不存在这样的集合)是2-coloring problem,其中:

    G = (V,E)
    V = { all nodes } 
    E = { (u,v) | u and v are "troubling each other" } 
    

    这个问题通过检查图形是否为bi-partite来解决,可以使用BFS来解决。


    当每个组应该有相同的元素时如何解决这个问题。

    首先,我们假设图是二分图,所以有一些解决方案。

    将图形拆分为一组连通分量:(S1,S2,S3,...,Sk)
    每个连通分量实际上是一个子图 (Si = Li,Ri) - 其中 Li,Ri 是二部图的两侧(如果忽略 Li 和 Ri 的顺序,每个连通分量中只有一个这样的分裂)。

    创建一个新数组:

    arr[i] = |Li| - |Ri|   
    where |X| is the cardinality of X (number of elements in the set)
    

    现在,解决这个问题与解决partition problem 相同,可以在伪多项式时间内完成(即节点数的多项式)。

    分区问题的解决方案将每个arr[i] 拆分为AB,使得sum{A} 尽可能接近sum{B}。如果arr[i]A 中,则在您的解决方案中,将Li 涂上“1”,将Ri 涂上“2”。否则 - 做相反的事情。

    解决方案将是O(k*n+m),其中k 是连通分量的数量,n 是图中的节点数,m 是图中的边数。

    【讨论】:

    • 我错过了第二部分...无论如何,我想您必须按降序对数组 (arr) 进行排序,然后将每个项目添加到 A 或 B 取决于哪个项目的运行总数最低那时。
    • @gen-y-s 不,这是解决分区问题的贪婪方法,这是次优的。这是在 O(n*k) 时间内使用动态规划解决的
    • 好的,我看到了描述DP算法的文章的链接......我建议贪婪的方法没有看文章......
    猜你喜欢
    • 2019-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-10
    • 1970-01-01
    • 1970-01-01
    • 2018-08-30
    相关资源
    最近更新 更多