该问题来自Code jam。
问题:
有没有办法将图表的节点划分为两个组,以便任何两个不能保留在同一组中的节点应该在不同的组中。
这有什么标准算法吗?
当每个小组应该有相同的元素时,我该如何解决这个问题。
答案 0 :(得分:8)
首先,可行性问题(有这样的集合/不存在这样的集合)是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和Li的顺序,每个连通分量中只有一个这样的分裂) RI)。
创建一个新数组:
arr[i] = |Li| - |Ri|
where |X| is the cardinality of X (number of elements in the set)
现在,解决这个问题与求解partition problem相同,这可以在伪多项式时间内完成(这是节点数的多项式)。
分区问题的解决方案将每个arr[i]
拆分为A
或B
,以使sum{A}
尽可能接近sum{B}
。如果arr[i]
位于A
中,则在您的解决方案中,将Li
标记为“1”,将Ri
标记为“2”。否则 - 做相反的事情。
解决方案为O(k*n+m)
,其中k
为已连接组件的数量,n
为图表中的节点数,m
为图表中的边数
答案 1 :(得分:1)
您从给定节点构建图形(使用哈希表将名称映射到节点)然后使用BFS或DFS遍历图形并确定其二分(即,divisibe为两个不相交的集合,使得一组中的节点仅在"故障"另一组中的节点,但在其自己的集合中没有任何节点)。这是通过为BFS / DFS访问的每个节点分配一个布尔值,然后检查其任何访问的邻居是否具有相同的值来完成的,这意味着该图不是二分的(不能分成两组)。