Maximum Flow Minimum Cut (Ford Fulkerson Algorithm)

Dynamic Programming

C++ Code

This algorithm finds the maximum flow in a network. The network is represented by a graph with nodes and edges, where each edge has a capacity indicating the maximum amount of flow it can carry. The algorithm starts with an initial flow of zero and repeatedly finds an augmenting path from the source node to the sink node, which is a path that can increase the flow from the source to the sink. The algorithm then increases the flow along this path by the maximum amount possible (which is determined by the capacity of the bottleneck edge), and updates the residual graph (which represents the remaining capacity on each edge) accordingly.

Time Complexity: O(fn) where f is the maximum flow returned and n is the number of edges

            bool bfs(vector<vector<int>> &graph, vector<int> &parent, int starting, int goal)
            {

                vector<bool> visited;
                visited.resize(graph.size(), false);

                queue<int> q;
                q.push(starting);
                visited.at(starting) = true;
                parent.at(starting) = -1;

                while (!q.empty())
                {
                    int from = q.front();
                    q.pop();

                    for (int to = 0; to < graph.size(); to++)
                    {

                        if (visited.at(to) == false && graph.at(from).at(to) > 0)
                        {
                            parent.at(to) = from;
                            visited.at(to) = true;
                            q.push(to);

                            if (to == goal)
                            {
                                return true;
                            }
                        }
                    }
                }

                return false;
            }

            int ford_fulkerson(vector<vector<int>> &graph, int starting, int goal)
            {
                vector<vector<int>> residual_graph = graph;
                vector<int> parent(graph.size(), -1);

                int max_flow = 0;

                while (bfs(residual_graph, parent, starting, goal))
                {
                    // Finding the bottlneck
                    int path_flow = INT_MAX;

                    int current_node = goal;
                    while (current_node != starting)
                    {

                        int parent_node = parent.at(current_node);

                        path_flow = min(path_flow, residual_graph.at(parent_node).at(current_node));
                        current_node = parent.at(current_node);
                    }

                    current_node = goal;
                    while (current_node != starting)
                    {
                        int parent_node = parent.at(current_node);
                        residual_graph.at(parent_node).at(current_node) -= path_flow;
                        residual_graph.at(current_node).at(parent_node) += path_flow;
                        current_node = parent.at(current_node);
                    }

                    max_flow += path_flow;
                }

                return max_flow;
            }

            int main()
            {
                vector<vector<int>> graph = {{0, 16, 13, 0, 0, 0}, {0, 0, 10, 12, 0, 0}, {0, 4, 0, 0, 14, 0}, {0, 0, 9, 0, 0, 20}, {0, 0, 0, 7, 0, 4}, {0, 0, 0, 0, 0, 0}};

                cout << "The maximum possible flow is "
                    << ford_fulkerson(graph, 0, 5) << endl;
            }