Cod sursa(job #2916341)

Utilizator AlexNeaguAlexandru AlexNeagu Data 29 iulie 2022 13:31:06
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.41 kb
#include<bits/stdc++.h>
// #define int long long 
#define x first
#define y second 
using namespace std;

class BipartiteMatcher {
    // n - vertices from first group, k - vertices from second group
    // n will always be smaller than k 
    int n, k;
    vector<vector<int>> E;
    vector<bool> used, initially_used;
    vector<int> from_left;
public:
    BipartiteMatcher(int _n, int _k) : n(_n), k(_k) {
        E.resize(n + 1);
        from_left.assign(k + 1, -1);
        used.assign(n + 1, 0);
        initially_used.assign(n + 1, 0);

    }
    void AddEdge(int u, int v) {
        // u is from first group (smaller one), v is from the second group(bigger)
        E[u].push_back(v);
    }
    bool match(int v) {
        if(used[v]) return false;
        used[v] = true;
        for(auto it : E[v]) {
            if(from_left[it] == -1 || match(from_left[it])) {
                from_left[it] = v;
                return true;
            }
        }
        return false;
    }
    vector<pair<int,int>> compute_max_matching() {
        // Basic Heuristic, tries to match in a greedy way 
        for(int v = 1; v <= n; v++) {
            for(auto it : E[v]) {
                if(from_left[it] == -1) {
                    from_left[it] = v;
                    initially_used[v] = true;
                    break;
                }
            }
        }
        for(int v = 1; v <= n; ++v) {
            if(!initially_used[v]) {
                used.assign(n + 1, 0);
                match(v);
            }
        }
        vector<pair<int,int>> matching_edges;
        for(int i = 1; i <= k; ++i) {
            if(from_left[i] != -1) {
                matching_edges.push_back({from_left[i], i});
            }
        }
        return matching_edges;
    }
};


int n, k, m;
ifstream in("cuplaj.in");
ofstream out("cuplaj.out");

int32_t main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    
    in >> n >> k >> m;
    BipartiteMatcher Kuhn(min(n, k), max(n, k));
    for(int i = 0; i < m; ++i) {
        int u, v;
        in >> u >> v;
        if(n > k) swap(u, v);
        Kuhn.AddEdge(u, v);
    }
    vector<pair<int,int>> match = Kuhn.compute_max_matching();
    out << match.size() << '\n';
    for(auto it : match) {
        if(n > k) swap(it.first, it.second);
        out << it.first << ' ' << it.second << '\n'; 
    }
    return 0;
}