为什么必须在Edmonds-Karp最大流量中考虑后沿?

时间:2016-08-09 06:50:35

标签: c++ algorithm graph ford-fulkerson edmonds-karp

我试图在C ++中实现Edmonds-Karp以获得最大流量,而且我的写法略有不同:

  1. 我没有遍历残差图中的所有边,而是使用邻接列表浏览了原始图中的边。
  2. 使用min flow更新残差图时,我没有更新任何后边缘。
  3. 有趣的是,当我运行我的代码时,它给了我正确的结果。所以我去了Wikipedia's example,其中专门展示了后端的使用方式。当我将此图表提供给我的代码时,我再次得到了正确的答案。 我还检查了结果流矩阵,它与维基百科相同。

    有人可以解释为什么我们必须添加和更新后端,并举例说明它们是关键的吗?

    Here我编写的代码(更新后包含后边缘):

2 个答案:

答案 0 :(得分:4)

尝试以下案例:

int main() {
    Digraph<int> g(8);
    g.addEdge(0,1,1);
    g.addEdge(1,2,1);
    g.addEdge(2,4,1);
    g.addEdge(0,3,1);
    g.addEdge(3,4,1);
    g.addEdge(4,7,1);
    g.addEdge(3,5,1);
    g.addEdge(5,6,1);
    g.addEdge(6,7,1);

    cout<<g.maxFlowEdmondsKarp(0,7);

    return 0;
}

可视化: enter image description here

您的程序首先采用最短路0-3-4-7,然后无法找到0-1-2-4-70-3-5-6-7。你得到1,但2是正确的答案。

您是否已插入后边缘,然后您会找到以下路径:

  1. 0-3-4-7
  2. 0-1-2-4-3(back-edge!)-5-6-7,获得最大流量2。

答案 1 :(得分:3)

考虑以下流量网络 enter image description here

假设第一个流程是 s→u→v→t 。 (如果你反对说Edmonds-Karp的BFS永远不会选择这个,那么用 s v 之间以及 u <之间的一些顶点来增加图形。 / em>和 t )。

如果没有逆流 u→v ,则无法获得20的最佳流量。