网络流算法

时间:2012-10-02 09:22:42

标签: algorithm

我遇到了这样的问题:

我们得到了一个二分图。例如,

A1 B1
A2 B2
A3 B3
A4

这是邻接列表表示(假设图是双向的)

B1 -> A2, A3
B2 -> A2, A3, A4
B3 -> A1

最终结果应该是左侧(As)的所有节点都有1个输入边缘,同时 - 我们需要最小化需要走出各个Bs节点的最大边数。在这种情况下,答案是:

B3 can connect to A1
B2 can connect to A2, A4
B1 can connect to A3

所以这里需要在单个Bs节点之外的最大边数是2.我们不能覆盖所有的As,同时有一个B节点没有2个边缘从它出来覆盖As。

另一个例子:

A1 B1
A2 B2
A3 B3
A4 B4

B1 -> A1, A2, A3
B2 -> A1, A2, A3, A4
B3 -> A1, A2, A3
B4 -> A1, A2, A3

在这种情况下答案是:

B1 can connect to A1
B2 can connect to A4
B3 can connect to A3
B2 can connect to A2

这样我们将完全覆盖所有As,同时我们已经最小化了需要走出单个B的边缘的最大数量。所以这里需要从单个Bs节点出来的最大边数是1.

另一个例子:

A1 B1
A2 B2
A3 B3
A4
A5
A6

B1 -> A6
B2 -> A1, A2, A3, A4, A5
B3 -> 

在这种情况下,答案是5,即需要走出单个Bs的最大边数是5.不能少于此。

我已经实现了基本的ford fulkerson算法,我知道这也是网络流程,但不知道如何与它相关。

如果有人可以提供一些关于图表的提示,那就太好了。

由于

2 个答案:

答案 0 :(得分:3)

找到一个最佳解决方案 - 所有B最多只有一个边缘(如果存在)很简单:

  • 向图表添加源和接收器。来源将有一个 对于B列表中所有顶点的容量为1的边缘。
  • 所有(B,A)边缘的容量均为1.
  • 所有A将具有容量为1的外边缘。
  • 现在,运行流算法将产生最大数量 A中的顶点可以用每个只有一个B的B覆盖 走出前沿(最佳解决方案,如果存在)

编辑:

现在,基于上述想法,并且因为您正尝试将最大边数从单个B最小化到A(而不是它们的总数,正如我之前所想的那样) ,最佳解决方案很简单:

while there is no coverage:
   set capacity(source,b_k) = increase_size() (for each b_k in B)
   run max flow algorithm on the graph suggested above
return last flow found

复杂性为O(E*V*#iterations)(在此问题中f <= V,因此,如果ford-fulkerson为O(EV)),其中#iterations的复杂度可以在最小最大数量上线性完成你寻找,或使用指数增加,然后二次搜索范围(由Evkeny Kluev建议),在这个数字的日志中。 由于二分图中的E=O(V),我们得到的总数为O(V^2*log(V))

答案 1 :(得分:2)

将所有A连接到一个具有容量边缘的公共汇聚节点1.将所有B连接到一个具有可变容量C边缘的公共源节点。

在此图表中查找最大网络流量,当不是每个A都被覆盖时增加C,否则减少它。这意味着使用二分搜索找到C的最佳值。