c++graphbreadth-first-searchford-fulkersonedmonds-karp

How to save last BFS of Edmonds-Karp algorithm?


I have implemented the following C++ Edmonds-Karp algorithm:

#include <iostream>
// Part of Cosmos by  OpenGenus Foundation //
#include <limits.h>
#include <string.h>
#include <queue>
using namespace std;
#define V 6
/* Returns true if there is a path from source 's' to sink 't' in
 * residual graph. Also fills parent[] to store the path */
bool bfs(int rGraph[V][V], int s, int t, int parent[])
{
    // Create a visited array and mark all vertices as not visited
    bool visited[V];
    memset(visited, 0, sizeof(visited));
    // Create a queue, enqueue source vertex and mark source vertex
    // as visited
    queue <int> q;
    q.push(s);
    visited[s] = true;
    parent[s] = -1;
    // Standard BFS Loop
    while (!q.empty())
    {
        int u = q.front();
        q.pop();
        for (int v = 0; v < V; v++)
            if (visited[v] == false && rGraph[u][v] > 0)
            {
                q.push(v);
                parent[v] = u;
                visited[v] = true;
            }
    }
    // If we reached sink in BFS starting from source, then return
    // true, else false
    return visited[t] == true;
}
// Returns tne maximum flow from s to t in the given graph
int fordFulkerson(int graph[V][V], int s, int t)
{
    int u, v;
    // Create a residual graph and fill the residual graph with
    // given capacities in the original graph as residual capacities
    // in residual graph
    int rGraph[V][V]; // Residual graph where rGraph[i][j] indicates
                      // residual capacity of edge from i to j (if there
                      // is an edge. If rGraph[i][j] is 0, then there is not)
    for (u = 0; u < V; u++)
        for (v = 0; v < V; v++)
            rGraph[u][v] = graph[u][v];
    int parent[V];  // This array is filled by BFS and to store path
    int max_flow = 0;  // There is no flow initially
    // Augment the flow while tere is path from source to sink
    while (bfs(rGraph, s, t, parent))
    {
        // Find minimum residual capacity of the edges along the
        // path filled by BFS. Or we can say find the maximum flow
        // through the path found.
        int path_flow = INT_MAX;
        for (v = t; v != s; v = parent[v])
        {
            u = parent[v];
            path_flow = min(path_flow, rGraph[u][v]);
        }
        // update residual capacities of the edges and reverse edges
        // along the path
        for (v = t; v != s; v = parent[v])
        {
            u = parent[v];
            rGraph[u][v] -= path_flow;
            rGraph[v][u] += path_flow;
        }
        // Add path flow to overall flow
        max_flow += path_flow;
    }
    // Return the overall flow
    return max_flow;
}

(source: https://iq.opengenus.org/edmonds-karp-algorithm-for-maximum-flow/)

I would like to save the last BFS of the algorithm, so I can print the minimal cut (which would be {last BFS} {everything else not found in the last BFS})

How do I do that?

I have tried creating a BFS vector every time the bfs function is called, and reset it, but somehow it doesn't seem to work how I imagined:

in bfs function:

bool bfs(int rGraph[V][V], int s, int t, int parent[], vector<int>& search)
{
...

 while (!q.empty())
    {
        int u = q.front();
        search.push_back(u);        
        q.pop();
...

in the fordFulkerson section:

vector<int>tempsearch;
vector<int>search;
 while (bfs(rGraph, s, t, parent, search))
    {

...
     tempsearch.resize(search);
     tempsearch = search     //this is now a pseudo-code variant
     search.resize(0);
    }
//at this point tempsearch or search should be the last bfs, no?
return max_flow;


Solution

  • Okay so I found a solution. We need to have the visited array as a global array (or you can pass it through every single parameter list). This way, every time the array is refreshed, it is also saved in the whole program.

    From there, all we have to do is write the output function for the minimal cut:

    void printMinCut(){
        for(int i = 0; i < visited.size(); i++){
             if(visited[i] == true) cout << i;
        }
        cout << endl;
        for(int i = 0; i < visited.size(); i++){
             if(visited[i] == false) cout << i;
        }
    }
    

    And there you have it!