Cod sursa(job #3207232)

Utilizator LucaMihaiLM10Luca Ilie LucaMihaiLM10 Data 25 februarie 2024 15:53:25
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.21 kb
#include <bits/stdc++.h>

using namespace std;

struct BIPARTITE_MATCHING {
    const int undef = -1;
    int n, m;
    vector<bool> vis;
    vector<int> pairL, pairR;
    vector<vector<int>> adjL, adjR;
    vector<pair<int, int>> matching;
    vector<int> perm;

    void init( int _n, int _m ) {
        n = _n;
        m = _m;
        pairL.resize( n );
        for ( int u = 0; u < n; u++ )
            pairL[u] = undef;
        pairR.resize( m );
        for ( int v = 0; v < m; v++ )
            pairR[v] = undef;
        adjL.resize( n );
        adjR.resize( m );
        vis.resize( n );
        perm.resize( n );
    }

    void add_edge( int u, int v ) {
        adjL[u].push_back( v );
        adjR[v].push_back( u );
    }

    bool findPair( int u ) {
        if ( vis[u] )
            return false;

        vis[u] = true;
        for ( int v: adjL[u] ) {
            if ( pairR[v] == undef || findPair( pairR[v] ) ) {
                pairL[u] = v;
                pairR[v] = u;
                return true;
            }
        }
        return false;
    }

    void computeMaxMatching() {
        bool newMatch = true;

        while ( newMatch ) {
            newMatch = false;
            for ( int u = 0; u < n; u++ ) {
                vis[u] = false;
                random_shuffle( adjL[u].begin(), adjL[u].end() );
                perm[u] = u;
            }
            random_shuffle( perm.begin(), perm.end() );
            for ( int i = 0; i < n; i++ ) {
                int u = perm[i];
                if ( pairL[u] == undef && findPair( u ) )
                    newMatch = true;
            }
        }

        for ( int u = 0; u < n; u++ ) {
            if ( pairL[u] != undef )
                matching.push_back( { u, pairL[u] } );
        }
    }
} cuplaj;

int main() {
    ifstream cin( "cuplaj.in" );
    ofstream cout( "cuplaj.out" );
    int n, m, k;

    cin >> n >> m >> k;
    cuplaj.init( n + 1, m + 1 );

    for ( int i = 0; i < k; i++ ) {
        int u, v;
        cin >> u >> v;
        cuplaj.add_edge( u, v );
    }

    cuplaj.computeMaxMatching();
    cout << cuplaj.matching.size() << "\n";
    for ( pair<int, int> p: cuplaj.matching )
        cout << p.first << " " << p.second << "\n";

    return 0;
}