Cod sursa(job #3357779)

Utilizator TestLicenta123Test Test TestLicenta123 Data 13 iunie 2026 14:46:48
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.86 kb
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>

struct Network {
private:
    std::vector<std::vector<int>> adj;
    std::vector<std::vector<int>> capacity;
    std::vector<std::vector<int>> flow;
    std::vector<int> parent;
    int size;

    int augment(int source, int target) {
        parent.assign(size + 1, -1);
        parent[source] = -2;

        std::queue<std::pair<int, int>> q;
        q.emplace(source, 1e9);

        while (!q.empty()) {
            int node = q.front().first;
            int flow_val = q.front().second;
            q.pop();

            for (int neighbor : adj[node]) {
                if (parent[neighbor] == -1 && capacity[node][neighbor] - flow[node][neighbor] > 0) {
                    parent[neighbor] = node;
                    int new_flow = std::min(flow_val, capacity[node][neighbor] - flow[node][neighbor]);
                    if (neighbor == target) {
                        return new_flow;
                    }
                    q.emplace(neighbor, new_flow);
                }
            }
        }
        return 0;
    }

public:
    explicit Network(int n) : size(n) {
        adj.resize(size + 1);
        capacity.resize(size + 1, std::vector<int>(size + 1, 0));
        flow.resize(size + 1, std::vector<int>(size + 1, 0));
    }

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

    int max_flow(int source, int target) {
        int total_flow = 0;

        int flow_val;
        while ((flow_val = augment(source, target)) != 0) {
            total_flow += flow_val;
            int cur = target;
            while (cur != source) {
                int prev = parent[cur];
                flow[prev][cur] += flow_val;
                flow[cur][prev] -= flow_val;
                cur = prev;
            }
        }
        return total_flow;
    }

    const std::vector<std::vector<int>>& get_flow() const {
        return flow;
    }
};

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;

    Network network(n + m + 2);

    int source = 0, sink = n + m + 1;

    for (int i = 1; i <= n; ++i) {
        network.add_edge(source, i, 1);
    }
    for (int i = 1; i <= m; ++i) {
        network.add_edge(n + i, sink, 1);
    }

    for (int i = 0; i < k; ++i) {
        int x, y;
        std::cin >> x >> y;
        network.add_edge(x, n + y, 1);
    }

    std::cout << network.max_flow(source, sink) << '\n';
    auto& flow = network.get_flow();

    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            if (flow[i][n + j] > 0) {
                std::cout << i << " " << j << '\n';
            }
        }
    }

    return 0;
}