Cod sursa(job #3333022)

Utilizator coco11coraline kalbfleisch coco11 Data 10 ianuarie 2026 15:43:21
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.78 kb
#include <bits/stdc++.h>
using namespace std;

struct HopcroftKarp {
    int N, M;                          // |L| = N, |R| = M
    vector<vector<int>> adj;           // adj[u] = list of v in R connected to u in L (1-based)
    vector<int> pairU, pairV, dist;    // matchings and BFS distance

    HopcroftKarp(int n, int m) : N(n), M(m) {
        adj.assign(N + 1, {});
        pairU.assign(N + 1, 0);
        pairV.assign(M + 1, 0);
        dist.assign(N + 1, 0);
    }

    void addEdge(int u, int v) {
        // u in [1..N], v in [1..M]
        adj[u].push_back(v);
    }

    bool bfs() {
        queue<int> q;
        // Build BFS layer graph from all free U vertices
        for (int u = 1; u <= N; ++u) {
            if (pairU[u] == 0) {
                dist[u] = 0;
                q.push(u);
            } else {
                dist[u] = INT_MAX;
            }
        }

        bool foundAugPath = false;
        while (!q.empty()) {
            int u = q.front(); q.pop();
            for (int v : adj[u]) {
                int u2 = pairV[v];
                if (u2 == 0) {
                    // We reached a free vertex on the right: at least one shortest augmenting path exists
                    foundAugPath = true;
                } else if (dist[u2] == INT_MAX) {
                    dist[u2] = dist[u] + 1;
                    q.push(u2);
                }
            }
        }
        return foundAugPath;
    }

    bool dfs(int u) {
        for (int v : adj[u]) {
            int u2 = pairV[v];
            if (u2 == 0 || (dist[u2] == dist[u] + 1 && dfs(u2))) {
                pairU[u] = v;
                pairV[v] = u;
                return true;
            }
        }
        dist[u] = INT_MAX; // mark as visited / dead end
        return false;
    }

    int maxMatching() {
        int matching = 0;
        while (bfs()) {
            for (int u = 1; u <= N; ++u) {
                if (pairU[u] == 0 && dfs(u)) {
                    ++matching;
                }
            }
        }
        return matching;
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    // File I/O as required
    ifstream fin("cuplaj.in");
    ofstream fout("cuplaj.out");

    if (!fin) return 0;

    int N, M, E;
    fin >> N >> M >> E;

    HopcroftKarp hk(N, M);
    for (int i = 0; i < E; ++i) {
        int u, v;
        fin >> u >> v;
        // Validate bounds defensively (optional)
        if (1 <= u && u <= N && 1 <= v && v <= M)
            hk.addEdge(u, v);
    }

    int ans = hk.maxMatching();
    fout << ans << "\n";
    for (int u = 1; u <= N; ++u) {
        if (hk.pairU[u] != 0) {
            fout << u << " " << hk.pairU[u] << "\n";
        }
    }

    return 0;
}