codingstuff.io
ExploreTutorialsProblemsCS Subjects
Get Started
ExploreTutorialsProblemsCS Subjects
Get Started
codingstuff.io

Master the art of building software through interactive tutorials, real-world problems, and guided projects.

Pune, Maharashtra, India

codingstuffmail@gmail.com

Product

  • Explore
  • Tutorials
  • Problems
  • CS Subjects

Company

  • About
  • Contact
  • Privacy Policy
  • Terms & Conditions
  • Sitemap

© 2026 codingstuff.io. All rights reserved.

Built with ❤️ for developers everywhere

/
/
All Tutorials
🧮

Data Structures & Algorithms

54 / 65 topics
54Network Flow Problems55Ford-Fulkerson Method56Edmonds-Karp Algorithm57Dinic's Algorithm
Tutorials/Data Structures & Algorithms/Network Flow Problems
🧮Data Structures & Algorithms

Network Flow Problems

Updated 2026-04-20
4 min read

Introduction

Network flow problems are a fundamental class of optimization problems that model various real-world scenarios, such as transportation networks, computer networks, and resource allocation. These problems involve finding the maximum amount of flow that can be sent from a source node to a sink node in a network while respecting capacity constraints on the edges.

In this tutorial, we will explore the key concepts, algorithms, and best practices for solving network flow problems. We'll cover the Ford-Fulkerson method, the Edmonds-Karp algorithm, and the Dinic's algorithm, providing detailed explanations and real-world code examples in Python.

Key Concepts

Network Representation

A network is typically represented as a directed graph \( G = (V, E) \), where:

  • \( V \) is the set of vertices (nodes).
  • \( E \) is the set of edges with capacities \( c(u, v) \geq 0 \).

Two special nodes are defined:

  • Source Node (\( s \)): The node from which flow originates.
  • Sink Node (\( t \)): The node where flow terminates.

Flow and Residual Graph

A flow in a network is an assignment of values to the edges such that:

  1. For each edge \( (u, v) \), the flow \( f(u, v) \leq c(u, v) \).
  2. For every vertex \( v \neq s, t \), the total flow into \( v \) equals the total flow out of \( v \).

The residual graph \( G_f = (V, E_f) \) is a graph that shows the remaining capacity after subtracting the current flow from the original capacities. The residual capacity \( c_f(u, v) \) is defined as:

  • \( c_f(u, v) = c(u, v) - f(u, v) \)
  • \( c_f(v, u) = f(u, v) \)

Augmenting Path

An augmenting path in the residual graph from the source to the sink is a path where the residual capacity of every edge is positive. The maximum flow can be increased by pushing additional flow along this path.

Ford-Fulkerson Method

The Ford-Fulkerson method is a generic algorithm for computing the maximum flow in a network. It works by repeatedly finding augmenting paths and updating the flow until no more augmenting paths exist.

Pseudocode

def ford_fulkerson(graph, source, sink):
    parent = {}
    max_flow = 0
    
    while bfs(graph, source, sink, parent):
        path_flow = float('Inf')
        s = sink
        
        while s != source:
            path_flow = min(path_flow, graph[parent[s]][s])
            s = parent[s]
        
        v = sink
        while v != source:
            u = parent[v]
            graph[u][v] -= path_flow
            graph[v][u] += path_flow
            v = parent[v]
        
        max_flow += path_flow
    
    return max_flow

def bfs(graph, source, sink, parent):
    visited = {node: False for node in graph}
    queue = [source]
    visited[source] = True
    
    while queue:
        u = queue.pop(0)
        
        for v in graph[u]:
            if not visited[v] and graph[u][v] > 0:
                queue.append(v)
                visited[v] = True
                parent[v] = u
                
                if v == sink:
                    return True
    
    return False

Explanation

  1. Initialization: Start with a flow of zero.
  2. BFS for Augmenting Path: Use BFS to find an augmenting path from the source to the sink in the residual graph.
  3. Path Flow Calculation: Determine the maximum flow that can be pushed through this path.
  4. Update Residual Capacities: Adjust the capacities along the path by subtracting and adding the path flow.
  5. Repeat: Continue until no more augmenting paths are found.

Complexity

The time complexity of the Ford-Fulkerson method is \( O(VE^2) \), where \( V \) is the number of vertices and \( E \) is the number of edges. This can be improved with better path-finding techniques.

Edmonds-Karp Algorithm

The Edmonds-Karp algorithm is a specific implementation of the Ford-Fulkerson method that uses BFS to find augmenting paths, ensuring that the shortest augmenting path (in terms of the number of edges) is always chosen. This guarantees a polynomial time complexity.

Pseudocode

def edmonds_karp(graph, source, sink):
    parent = {}
    max_flow = 0
    
    while bfs(graph, source, sink, parent):
        path_flow = float('Inf')
        s = sink
        
        while s != source:
            path_flow = min(path_flow, graph[parent[s]][s])
            s = parent[s]
        
        v = sink
        while v != source:
            u = parent[v]
            graph[u][v] -= path_flow
            graph[v][u] += path_flow
            v = parent[v]
        
        max_flow += path_flow
    
    return max_flow

def bfs(graph, source, sink, parent):
    visited = {node: False for node in graph}
    queue = [source]
    visited[source] = True
    
    while queue:
        u = queue.pop(0)
        
        for v in graph[u]:
            if not visited[v] and graph[u][v] > 0:
                queue.append(v)
                visited[v] = True
                parent[v] = u
                
                if v == sink:
                    return True
    
    return False

Explanation

The Edmonds-Karp algorithm is identical to the Ford-Fulkerson method, but it uses BFS to find augmenting paths. This ensures that the shortest path (in terms of the number of edges) is always chosen, leading to a polynomial time complexity.

Complexity

The time complexity of the Edmonds-Karp algorithm is \( O(VE^2) \), which is more efficient than the general Ford-Fulkerson method in practice.

Dinic's Algorithm

Dinic's algorithm is another efficient algorithm for solving network flow problems. It uses a blocking flow approach, where it finds multiple paths from the source to the sink simultaneously, ensuring that each path is part of a blocking flow.

Pseudocode

def dinics(graph, source, sink):
    max_flow = 0
    
    while bfs(graph, source, sink):
        level = {}
        for node in graph:
            level[node] = float('Inf')
        
        level[source] = 0
        queue = [source]
        
        while queue:
            u = queue.pop(0)
            
            for v in graph[u]:
                if level[v] == float('Inf') and graph[u][v] > 0:
                    level[v] = level[u] + 1
                    queue.append(v)
        
        if level[sink] == float('Inf'):
            break
        
        parent = {}
        max_flow += dfs(graph, source, sink, parent, level, float('Inf'))
    
    return max_flow

def bfs(graph, source, sink, level):
    visited = {node: False for node in graph}
    queue = [source]
    visited[source] = True
    
    while queue:
        u = queue.pop(0)
        
        for v in graph[u]:
            if not visited[v] and graph[u][v] > 0 and level[v] == float('Inf'):
                level[v] = level[u] + 1
                queue.append(v)
    
    return level[sink] != float('Inf')

def dfs(graph, u, sink, parent, level, flow):
    if u == sink:
        return flow
    
    for v in graph[u]:
        if level[v] == level[u] + 1 and graph[u][v] > 0:
            new_flow = min(flow, graph[u][v])
            temp_flow = dfs(graph, v, sink, parent, level, new_flow)
            
            if temp_flow > 0:
                graph[u][v] -= temp_flow
                graph[v][u] += temp_flow
                return temp_flow
    
    return 0

Explanation

  1. Level Graph Construction: Use BFS to construct a level graph where each node is assigned a level based on the shortest distance from the source.
  2. Blocking Flow Search: Use DFS to find blocking flows in the level graph, pushing flow along augmenting paths until no more paths can be found.
  3. Update Residual Capacities: Adjust the capacities along the paths by subtracting and adding the path flow.
  4. Repeat: Continue until no more blocking flows are found.

Complexity

The time complexity of Dinic's algorithm is \( O(V^2E) \), which is generally faster than the Edmonds-Karp algorithm for large networks.

Best Practices

  1. Choose the Right Algorithm: Use Ford-Fulkerson for small networks, Edmonds-Karp for moderate-sized networks, and Dinic's for larger networks.
  2. Input Validation: Ensure that the input graph is valid and that all capacities are non-negative.
  3. Edge Cases: Handle edge cases such as disconnected graphs or graphs with no feasible flow.
  4. Optimization: Use data structures like adjacency lists for efficient graph representation and consider parallel processing for very large networks.

Conclusion

Network flow problems are a powerful tool for modeling and solving real-world optimization challenges. By understanding the key concepts, algorithms, and best practices, you can effectively tackle these problems in various domains. Whether you're optimizing transportation routes or managing computer network traffic, network flow techniques provide valuable insights and solutions.


PreviousHamiltonian CyclesNext Ford-Fulkerson Method

Recommended Gear

Hamiltonian CyclesFord-Fulkerson Method