{"id":2296,"date":"2026-07-20T12:43:14","date_gmt":"2026-07-20T10:43:14","guid":{"rendered":"https:\/\/kindsonthegenius.com\/blog\/ford-fulkerson-algorithm-in-flow-networks\/"},"modified":"2026-08-26T20:46:44","modified_gmt":"2026-08-26T18:46:44","slug":"ford-fulkerson-algorithm-in-flow-networks","status":"publish","type":"post","link":"https:\/\/kindsonthegenius.com\/blog\/ford-fulkerson-algorithm-in-flow-networks\/","title":{"rendered":"Ford-Fulkerson Algorithm in Flow Networks"},"content":{"rendered":"<p><!-- ktg-updated-banner --><\/p>\n<p><em>Updated August 2026 \u2014 tutorial restored for this URL.<\/em><\/p>\n<p>We are going to consider the <strong>Ford-Fulkerson<\/strong> method, which finds a <strong>maximum flow<\/strong> in a flow network. If you are new to the topic, read <a href=\"https:\/\/kindsonthegenius.com\/blog\/introduction-to-network-flow\/\">Introduction to Network Flow<\/a> and <a href=\"https:\/\/kindsonthegenius.com\/blog\/network-flow-introduction-to-cuts-in-a-network\/\">Cuts in a Network<\/a> first. A worked companion post is also here: <a href=\"https:\/\/kindsonthegenius.com\/blog\/the-ford-fulkerson-algorithm\/\">The Ford-Fulkerson Algorithm<\/a>.<\/p>\n<p>We will cover:<\/p>\n<ol>\n<li><a href=\"#t1\">What is a flow network?<\/a><\/li>\n<li><a href=\"#t2\">What Ford-Fulkerson does<\/a><\/li>\n<li><a href=\"#t3\">Residual graph and augmenting paths<\/a><\/li>\n<li><a href=\"#t4\">Algorithm steps<\/a><\/li>\n<li><a href=\"#t5\">Small example<\/a><\/li>\n<li><a href=\"#t6\">Complexity and variants<\/a><\/li>\n<li><a href=\"#t7\">Where to go next<\/a><\/li>\n<\/ol>\n<p><strong id=\"t1\">1. What is a flow network?<\/strong><\/p>\n<p>A flow network is a directed graph where each edge has a non-negative <strong>capacity<\/strong>. We designate:<\/p>\n<ul>\n<li><strong>Source<\/strong> <code>s<\/code> \u2014 where flow starts<\/li>\n<li><strong>Sink<\/strong> <code>t<\/code> \u2014 where flow ends<\/li>\n<\/ul>\n<p>A <strong>flow<\/strong> assigns a value to each edge such that:<\/p>\n<ul>\n<li>0 \u2264 flow(e) \u2264 capacity(e)<\/li>\n<li>For every vertex except <code>s<\/code> and <code>t<\/code>, inflow = outflow (conservation)<\/li>\n<\/ul>\n<p>The <strong>value<\/strong> of the flow is the net amount leaving the source (equivalently, entering the sink).<\/p>\n<p><strong id=\"t2\">2. What Ford-Fulkerson does<\/strong><\/p>\n<p>Ford-Fulkerson repeatedly finds a path from <code>s<\/code> to <code>t<\/code> that can still carry more flow (an <strong>augmenting path<\/strong>), pushes as much as possible along that path, and updates residual capacities \u2014 until no augmenting path remains. At that point the flow is maximum (max-flow min-cut theorem).<\/p>\n<p><strong id=\"t3\">3. Residual graph and augmenting paths<\/strong><\/p>\n<p>The <strong>residual graph<\/strong> tracks leftover capacity:<\/p>\n<ul>\n<li>Forward residual edge: capacity \u2212 current flow<\/li>\n<li>Backward residual edge: current flow (lets you \u201cundo\u201d flow)<\/li>\n<\/ul>\n<p>An <strong>augmenting path<\/strong> is any <code>s<\/code>\u2192<code>t<\/code> path in the residual graph with positive residual capacity on every edge.<\/p>\n<p>Bottleneck of a path = minimum residual capacity on that path. That is how much flow you can add in one augmentation.<\/p>\n<p><strong id=\"t4\">4. Algorithm steps<\/strong><\/p>\n<ol>\n<li>Start with flow = 0 on every edge.<\/li>\n<li>Build the residual graph.<\/li>\n<li>While there exists an augmenting path <code>p<\/code> from <code>s<\/code> to <code>t<\/code>:\n<ul>\n<li>Let <code>b =<\/code> bottleneck(p)<\/li>\n<li>For each forward edge on <code>p<\/code>: flow += <code>b<\/code><\/li>\n<li>For each backward edge on <code>p<\/code>: flow \u2212= <code>b<\/code><\/li>\n<li>Update residual capacities<\/li>\n<\/ul>\n<\/li>\n<li>When no path remains, return the flow value.<\/li>\n<\/ol>\n<p>Pseudocode:<\/p>\n<pre><code>Ford-Fulkerson(G, s, t):\n    flow \u2190 0 for all edges\n    while exists path p from s to t in residual(G):\n        b \u2190 min residual capacity on p\n        augment flow along p by b\n    return value(flow)\n<\/code><\/pre>\n<p><strong id=\"t5\">5. Small example (intuition)<\/strong><\/p>\n<p>Suppose <code>s \u2192 a<\/code> has capacity 10, <code>a \u2192 t<\/code> has capacity 6, and <code>s \u2192 t<\/code> has capacity 3.<\/p>\n<ul>\n<li>First path <code>s-a-t<\/code> can push 6 (bottleneck at <code>a-t<\/code>). Flow value = 6.<\/li>\n<li>Residual: <code>s-a<\/code> has 4 left; <code>a-t<\/code> is saturated.<\/li>\n<li>Next path <code>s-t<\/code> can push 3. Flow value = 9.<\/li>\n<li>No more augmenting path \u2192 maximum flow is 9.<\/li>\n<\/ul>\n<p>Work the same idea on larger graphs by always searching the residual graph (DFS or BFS).<\/p>\n<p><strong>Python-style sketch<\/strong> (educational \u2014 not production-optimized):<\/p>\n<pre><code>from collections import defaultdict, deque\n\ndef edmonds_karp(capacity, s, t):\n    # capacity[u][v] = residual capacity\n    def bfs():\n        parent = {s: None}\n        q = deque([s])\n        while q:\n            u = q.popleft()\n            for v, cap in capacity[u].items():\n                if v not in parent and cap &gt; 0:\n                    parent[v] = u\n                    if v == t:\n                        return parent\n                    q.append(v)\n        return None\n\n    flow_value = 0\n    while True:\n        parent = bfs()\n        if not parent:\n            break\n        # bottleneck\n        v = t\n        b = float(\"inf\")\n        while v != s:\n            u = parent[v]\n            b = min(b, capacity[u][v])\n            v = u\n        # augment\n        v = t\n        while v != s:\n            u = parent[v]\n            capacity[u][v] -= b\n            capacity[v][u] += b\n            v = u\n        flow_value += b\n    return flow_value\n<\/code><\/pre>\n<p>Initialize <code>capacity<\/code> as a nested dict of edge capacities, and add reverse edges with 0 capacity before running.<\/p>\n<p><strong id=\"t6\">6. Complexity and variants<\/strong><\/p>\n<ul>\n<li>Classic Ford-Fulkerson (DFS, arbitrary path choice) can be slow if capacities are large and path choice is unlucky.<\/li>\n<li><strong>Edmonds-Karp<\/strong> = Ford-Fulkerson using BFS for the shortest augmenting path \u2192 O(VE\u00b2).<\/li>\n<li>Faster algorithms (Dinic, push-relabel) exist for competitive programming and large graphs.<\/li>\n<\/ul>\n<p><strong id=\"t7\">7. Where to go next<\/strong><\/p>\n<ul>\n<li><a href=\"https:\/\/kindsonthegenius.com\/blog\/the-ford-fulkerson-algorithm\/\">The Ford-Fulkerson Algorithm<\/a> \u2014 more worked detail<\/li>\n<li><a href=\"https:\/\/kindsonthegenius.com\/blog\/introduction-to-network-flow\/\">Introduction to Network Flow<\/a><\/li>\n<li><a href=\"https:\/\/kindsonthegenius.com\/blog\/network-flow-introduction-to-cuts-in-a-network\/\">Cuts in a Network<\/a> \u2014 connect max-flow to min-cut<\/li>\n<li><a href=\"https:\/\/kindsonthegenius.com\/blog\/ford-fulkerson-algorithm-for-max-flow-problem\/\">Ford-Fulkerson for Max Flow Problem<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Updated August 2026 \u2014 tutorial restored for this URL. We are going to consider the Ford-Fulkerson method, which finds a maximum flow in a flow &hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"pagelayer_contact_templates":[],"_pagelayer_content":"","footnotes":""},"categories":[35],"tags":[],"class_list":["post-2296","post","type-post","status-publish","format-standard","hentry","category-algorithms"],"acf":[],"_links":{"self":[{"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/posts\/2296","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/comments?post=2296"}],"version-history":[{"count":2,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/posts\/2296\/revisions"}],"predecessor-version":[{"id":2437,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/posts\/2296\/revisions\/2437"}],"wp:attachment":[{"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/media?parent=2296"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/categories?post=2296"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/tags?post=2296"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}