Search code examples
c++max-flow

Error in MAXFLOW-MINCUT code


I have written a Max-Flow class using the edmonds-karp implementation. The code seems to work correctly when I try to get the value of the max flow. I submitted the code on SPOJ TotalFlow so I believe the implementation is correct.

But I am trying to get the Min-Cut from the residual graph. This has led to some errors. Any help would be useful.

#include <iostream>
#include <vector>
#include <queue>

using namespace std;

class EdmondsKarp
{
private:
    vector<vector<int>> graph;
    vector<vector<int>> rGraph;
    vector<vector<int>> capacities;
    vector<int> parent;
    vector<bool> visited;
    int source, sink;
    int flow;
public:
    EdmondsKarp(vector<vector<int>> graph, vector<vector<int>> capacities, int source, int sink)
    {
        this->graph = graph;
        this->capacities = capacities;
        this->rGraph = capacities;
        this->source = source;
        this->sink = sink;
        parent.resize(rGraph.size());
        visited.resize(rGraph.size());
        makeFlow();
    }
    bool bfs()
    {
        for (int i = 0; i < visited.size(); i++)
        {
            visited[i] = false;
        }

        queue<int> q;
        visited[source] = true;
        parent[source] = -1;
        q.push(source);
        int qf, v;
        while (!q.empty())
        {
            qf = q.front();
            q.pop();
            for (int i = 0; i < graph[qf].size(); i++)
            {
                v = graph[qf][i];
                if (!visited[v] && rGraph[qf][v] > 0)
                {
                    q.push(v);
                    parent[v] = qf;
                    visited[v] = true;
                }
            }
        }
        return visited[sink];
    }

    int makeFlow()
    {
        int INF = 9 + 1e9;
        flow = 0;
        int u, v, path_flow;
        while (bfs())
        {
            path_flow = INF;
            for (v = sink; v != source; v = parent[v])
            {
                u = parent[v];
                path_flow = min(path_flow, rGraph[u][v]);
            }

            for (v = sink; v != source; v = parent[v])
            {
                u = parent[v];
                rGraph[u][v] -= path_flow;
                rGraph[v][u] += path_flow;
            }
            flow += path_flow;
        }
        return 1;
    }

    int getFlow()
    {
        return flow;
    }

    vector<vector<int>> getFlowGraph()
    {
        vector<vector<int>> flowGraph(capacities.size(), vector<int>(capacities.size(), 0));
        for (int i = 0; i < capacities.size(); i++)
        {
            for (int j = 0; j < capacities[i].size(); j++)
            {
                if (capacities[i][j] > 0)
                {
                    flowGraph[i][j] = capacities[i][j] - rGraph[i][j];
                }
            }
        }
        return flowGraph;
    }

    vector<int> getMinCut()
    {
        vector<int> cut;
        bfs();
        int cutsize = 0;
        for (int i = 0; i < visited.size(); i++)
        {
            if (visited[i])
            {
                cut.push_back(i);
                for (int j = 0; j < graph[i].size(); j++)
                {
                    if (!visited[graph[i][j]])
                    {
                        cutsize += capacities[i][graph[i][j]];
                    }
                }
            }
        }
        cout << cutsize << endl;
        return cut;
    }
};

My main function is the following

int main()
{
    vector<vector<int>> graph(300, vector<int>(0)), capacities(300, vector<int>(300, 0));
    int m, w;
    char x, y;
    cin >> m;
    while (m--)
    {
        cin >> x >> y >> w;
        graph[x].push_back(y);
        capacities[x][y] += w;
        graph[y].push_back(x);
        capacities[y][x] += w;
    }
    EdmondsKarp edk(graph, capacities, 'A', 'Z');
    edk.getMinCut();
}

Solution

  • So I managed to fix the getMinCut function. Unfortunately I have not figured out what was wrong in the original code. I am nor running through all possible edge combinations and adding the appropriate ones to the cut.

    vector<int> getMinCut()
    {
      vector<int> cut;
      bfs();
      for (int i = 0; i < visited.size(); i++)
      {
        if(visited[i])
        {
          cut.push_back(i);
        }
      }
      int cutsize = 0;
      for (int i = 0; i < graph.size(); i++)
      {
        for (int j = 0; j < graph.size(); j++)
        {
          if(visited[i] && !visited[j])
          {
            cutsize += capacities[i][j];
          }
        }
      }
      cout << cutsize << endl;
      return cut;
    }