Problem p02378 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <queue>
#include <set>
#include <vector>

class BipartiteGraph {
public:
  BipartiteGraph(const int x, const int y)
      : size_x_(x), size_y_(y), edge_(x + y) {}

  void add_xy(const int vx, const int vy) { edge_[vx].insert(size_x_ + vy); }

  int matching() const {
    std::vector<int> match_to(edge_.size(), -1);
    int count = 0;
    for (int i = 0; i < size_x_; ++i) {
      std::vector<bool> visited(edge_.size(), false);
      if (FordFullkerson(i, match_to, visited))
        ++count;
    }
    return count;
  }

private:
  bool FordFullkerson(int from, std::vector<int> &match_to,
                      std::vector<bool> &visited) const {
    if (from == -1)
      return true;
    if (visited[from])
      return false;
    visited[from] = true;
    for (const auto &to : edge_[from]) {
      if (!FordFullkerson(match_to[to], match_to, visited))
        continue;
      match_to[from] = to;
      match_to[to] = from;
      return true;
    }
    return false;
  }

  std::vector<std::set<int>> edge_;
  int size_x_, size_y_;
};

////////////////////////////////////////////////////////////////////////////////

#include <iostream>
using namespace std;

int main() {
  int x, y, e;
  cin >> x >> y >> e;
  BipartiteGraph g(x, y);
  for (int i = 0; i < e; ++i) {
    int vx, vy;
    cin >> vx >> vy;
    g.add_xy(vx, vy);
  }
  cout << g.matching() << endl;
}

Error: 0

Fixed submission:


#include <iostream>
using namespace std;

#include <algorithm>
#include <queue>
#include <set>
#include <tuple>
#include <vector>

class BipartiteGraph {
public:
  BipartiteGraph(const int x, const int y)
      : size_x_(x), size_y_(y), edge_(x + y) {}

  void add_xy(const int vx, const int vy) { edge_[vx].insert(size_x_ + vy); }

  int matching() const {
    int source = size_x_ + size_y_;
    int sink = source + 1;
    std::vector<std::set<int>> edge = edge_;
    edge.insert(edge.end(), std::set<int>());
    edge.insert(edge.end(), std::set<int>());
    for (int vx = 0; vx < size_x_; ++vx)
      edge[source].insert(vx);
    for (int vy = 0; vy < size_y_; ++vy)
      edge[size_x_ + vy].insert(sink);

    int count = 0;
    while (true) {
      auto path = EdmondsKarp(edge);
      if (path.empty())
        break;
      for (int i = 1; i < path.size(); ++i) {
        edge[path[i - 1]].erase(path[i]);
        edge[path[i]].insert(path[i - 1]);
      }
      ++count;
    }
    //         while(true) {
    //             std::vector<int> path;
    //             path.push_back(source);
    //             if(!FordFullkerson(edge, path)) break;
    //             for(int i = 1; i < path.size(); ++i) {
    //                 edge[path[i - 1]].erase(path[i]);
    //                 edge[path[i]].insert(path[i - 1]);
    //             }
    //             ++count;
    //             cout<<count<<endl;
    //         }
    return count;
  }

private:
  bool FordFullkerson(const std::vector<std::set<int>> &edge,
                      std::vector<int> &path) const {
    //         cout<<path.size()<<endl;
    //         for(auto&v:path)cout<<" "<<v;cout<<endl;
    if (path.back() == size_x_ + size_y_ + 1)
      return true;
    for (const auto &to : edge[path.back()]) {
      if (std::find(path.begin(), path.end(), to) != path.end())
        continue;
      path.push_back(to);
      if (FordFullkerson(edge, path))
        return true;
      path.pop_back();
    }
    return false;
  }
  std::vector<int> EdmondsKarp(const std::vector<std::set<int>> &edge) const {
    //         typedef std::tuple<int, std::vector<int>> Node;
    //         std::vector<int> path;
    std::queue<std::vector<int>> q;
    q.push({size_x_ + size_y_});
    while (!q.empty()) {
      auto path = q.front();
      q.pop();
      if (path.back() == size_x_ + size_y_ + 1)
        return path;
      for (const auto &to : edge[path.back()]) {
        if (std::find(path.begin(), path.end(), to) != path.end())
          continue;
        path.push_back(to);
        q.push(path);
        path.pop_back();
      }
    }

    return std::vector<int>();
    //         return path;
  }

  std::vector<std::set<int>> edge_;
  int size_x_, size_y_;
};

////////////////////////////////////////////////////////////////////////////////

#include <iostream>
using namespace std;

int main() {
  int x, y, e;
  cin >> x >> y >> e;
  BipartiteGraph g(x, y);
  for (int i = 0; i < e; ++i) {
    int vx, vy;
    cin >> vx >> vy;
    g.add_xy(vx, vy);
  }
  cout << g.matching() << endl;
}