Cod sursa(job #3220613)

Utilizator AleXutzZuDavid Alex Robert AleXutzZu Data 4 aprilie 2024 13:11:29
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.42 kb
#include <iostream>
#include <vector>
#include <queue>

constexpr const int INF = 1e9;

struct Matching {
private:
    std::vector<std::vector<int>> adj;
    std::vector<int> match;
    std::vector<int> dist;
    int size;

    bool alternate() {
        std::queue<int> queue;

        for (int i = 1; i <= size; ++i) {
            if (!match[i]) {
                queue.push(i);
                dist[i] = 0;
            } else dist[i] = INF;
        }

        dist[0] = INF;

        while (!queue.empty()) {
            auto top = queue.front();
            queue.pop();

            if (dist[top] >= dist[0]) continue;

            for (const auto &x: adj[top]) {
                if (dist[match[x]] == INF) {
                    dist[match[x]] = dist[top] + 1;
                    queue.push(match[x]);
                }
            }
        }
        return dist[0] != INF;
    }

    bool augment(int node) {
        if (node == 0) return true;
        for (const auto &x: adj[node]) {
            if (dist[match[x]] == 1 + dist[node] && augment(match[x])) {
                match[node] = x;
                match[x] = node;
                return true;
            }
        }
        dist[node] = INF;
        return false;
    }

public:
    explicit Matching(int size) : size(size) {
        adj.resize(size + 1);
        match.resize(size + 1);
        dist.resize(size + 1);
    }

    void add_edge(int x, int y) {
        adj[x].push_back(y);
        adj[y].push_back(x);
    }

    int max_match() {
        int ans = 0;

        while (alternate()) {
            for (int i = 1; i <= size; ++i) {
                if (!match[i] && augment(i)) ans++;
            }
        }

        return ans;
    }

    std::vector<int> get_matches() const {
        return match;
    }
};

int main() {
    freopen("cuplaj.in", "r", stdin);
    freopen("cuplaj.out", "w", stdout);
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);

    int n, m, k;
    std::cin >> n >> m >> k;

    Matching match(n + m);

    while (k--) {
        int x, y;
        std::cin >> x >> y;
        match.add_edge(x, n + y);
    }

    std::cout << match.max_match() << '\n';
    auto pairs = match.get_matches();

    for (int i = 1; i <= n; ++i) {
        if (match[i]) std::cout << i << " " << match[i] - n << '\n';
    }
    return 0;
}