Cod sursa(job #2663981)

Utilizator mihnea.anghelMihnea Anghel mihnea.anghel Data 27 octombrie 2020 18:29:41
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.57 kb
#include <fstream>
#include <vector>
#include <bitset>
#define f in
#define g out

using namespace std;
ifstream in ( "cuplaj.in" );
ofstream out( "cuplaj.out" );
int n, m, k, i, j, ok, x, y, sol;
int st[10100], dr[10100];
vector<int> L[10100];
bitset<10100> fr;

// in st[i] tin nodul din dreapta cu care e cuplat nodul i din stanga
// in dr[i] tin nodul din stanga cu care e cuplat nodul i din dreapta
// ambele vor avea valoarea 0 daca nodul e necuplat
int cupleaza( int nod ){
    if ( fr[nod] )
        return 0; //daca am mai fost pe aici in seamna ca nu ne ajuta
    fr[nod] = 1;

    // incerc sa-l cuplez pe nod cu unul din vecinii lui directi din dreapta necuplati
    for ( auto vecin: L[nod] )
        if ( !dr[vecin] ){
            st[nod] = vecin;
            dr[vecin] = nod;
            sol++;
            return 1;
        }
    
    // daca nu a mers, caut un vecin cuplat din dreapta,
    // al carui vecin din stanga poate fi cuplat altfel
    for ( auto vecin: L[nod] )
        if( cupleaza(dr[vecin]) ){
            st[nod] = vecin;
            dr[vecin] = nod;
            return 1;
        }
    return 0;
}


int main() {
    f>>n>>m>>k;
    for ( i=1; i <= k; i++ ){
        f>>x>>y;
        L[x].push_back(y);
        //tinem vecinii din dreapta ai nodurilor din stanga
    }
    
    ok = 1;
    while ( ok ) {
        ok = 0;
        fr.reset();
        for ( i=1; i <= n; i++ )
            if ( st[i] == 0 && cupleaza(i) )
                ok = 1;
    }
    g<<sol<<"\n";
    for ( i=1; i <= n; i++ )
        if ( st[i] )
            g<<i<<" "<<st[i]<<"\n";
    return 0;
}