Cod sursa(job #2430474)

Utilizator freak93Adrian Budau freak93 Data 15 iunie 2019 00:27:16
Problema Cuplaj maxim in graf bipartit Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.93 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <utility>
#include <cassert>

using namespace std;

class Graph {
  public:
    Graph(int size_left, int size_right):
        m_edges(size_left),
        m_used(size_left),
        m_left(size_left, -1),
        m_right(size_right, -1) {}

    void add_edge(int from, int to) {
        m_edges[from].push_back(to);
    }

    int size() const {
        return m_edges.size();
    }

    vector< pair<int, int> > match() {
        for (auto &edges : m_edges)
            random_shuffle(edges.begin(), edges.end());

        while (true) {
            fill(m_used.begin(), m_used.end(), false);
            bool try_again = false;
            for (int i = 0; i < size(); ++i)
                if (m_left[i] == -1)
                    try_again = (try_again || go(i));
            if (!try_again)
                break;
        }

        vector< pair<int, int> > match;
        for (int i = 0; i < size(); ++i)
            if (m_left[i] != -1)
                match.emplace_back(i, m_left[i]);
        return match;
    }

  private:
    bool go(int node) {
        if (m_used[node])
            return false;
        m_used[node] = true;

        for (auto &next : m_edges[node])
            if (m_right[next] == -1 || go(m_right[next])) {
                m_left[node] = next;
                m_right[next] = node;
                return true;
            }
        return false;
    }

    vector< vector<int> > m_edges;
    vector<bool> m_used;
    vector<int> m_left;
    vector<int> m_right;
};

int main() {
    ifstream cin("cuplaj.in");
    ofstream cout("cuplaj.out");

    int N, M, E; cin >> N >> M >> E;
    Graph G(N, M);
    for (int i = 0; i < E; ++i) {
        int x, y; cin >> x >> y;
        G.add_edge(x - 1, y - 1);
    }

    auto match = G.match();
    cout << match.size() << "\n";
    for (auto &p : match)
        cout << p.first + 1 << " " << p.second + 1 << "\n";
}