-1

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();
}
David G
  • 94,763
  • 41
  • 167
  • 253
epsilon_0
  • 11
  • 4
  • "led to some errors" is a little generic, maybe you should elaborate – Leeor Dec 09 '14 at 22:27
  • Ok changing the statement. I meant that the value of cutsize was wrong. It is not giving me the correct answer. – epsilon_0 Dec 09 '14 at 22:29
  • For what input? what was the value you received and what did you expect? Please add these to your question, and try to find the simplest example that reproduces this problem – Leeor Dec 09 '14 at 22:32
  • Unfortunately SPOJ does not give out the test data. So I am unable to find the correct test case. I have tried generating 5-6 small test cases but have been unable to find a discrepancy. – epsilon_0 Dec 09 '14 at 22:35

1 Answers1

0

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;
}
epsilon_0
  • 11
  • 4