Cod sursa(job #2952926)

Utilizator dana24hdDana N dana24hd Data 10 decembrie 2022 11:07:14
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.25 kb
#include <iostream>
#include <fstream>
#include <bits/stdc++.h>

using namespace std;

const int NIL = 0;
const int INF = INT_MAX;
const int N_MAX = 10005;


ifstream in("cuplaj.in");
ofstream out("cuplaj.out");

int mat[105][105];
int ordinePar[N_MAX];
int ordineImpar[N_MAX];

/// m nr de noduri din stanga ( i+j par )
/// n nr de noduri din dreapta ( i+j impar )
int m, n;

/// nodurile adiacente cu nodul u din stanga
vector<int> adj[N_MAX];


/// perechea fiecarui nod u din stanga
int pairU[N_MAX];

/// perechea fiecarui nod v din dreapta
int pairV[N_MAX];

/// distanta
int dist[N_MAX];

/// daca avem sau nu cale alternativa
bool bfs() {
    queue<int> Q;

    for (int u=1; u<=m; u++){

        /// nod fara pereche
        if (pairU[u]==NIL){
            dist[u] = 0;
            Q.push(u);
        }else
            dist[u] = INF;
        /// distanta infinita pentru a-l lua din nou
    }

    dist[NIL] = INF;

    /// Q are doar noduri din stanga
    while ( !Q.empty() ) {

        int u = Q.front();
        Q.pop();

        /// nu e NIL, dar are distanta mai scurta catre NIL
        if (dist[u] < dist[NIL]) {
            /// toti vecinii lui u
            for (int i=0; i<adj[u].size(); i++)
            {
                int v = adj[u][i];

                /// nu a fost luat inca in considerare cuplajul acesta
                if (dist[pairV[v]] == INF){
                    /// luam in considerare perechea
                    dist[pairV[v]] = dist[u] + 1;
                    Q.push(pairV[v]);
                }
            }
        }
    }

    /// daca ne putem intoarce la NIL exista cale alternativa
    return (dist[NIL] != INF);
}

/// daca exista cale alternativa incepand cu u
bool dfs(int u)
{
    if (u != NIL) {

        for (int i=0; i<adj[u].size(); i++) {

            /// vecinii
            int v = adj[u][i];

            /// distanta de la BFS
            if (dist[pairV[v]] == dist[u]+1)
            {
                /// daca si dfs pentru perechea lui e true
                if (dfs(pairV[v]) == true)
                {
                    pairV[v] = u;
                    pairU[u] = v;
                    return true;
                }
            }
        }

        /// nu exista cale alternativa
        dist[u] = INF;
        return false;
    }
    return true;
}

/// cuplajul maxim
int maxMatch(){

    for (int u=0; u<=m; u++)
        pairU[u] = NIL;
    for (int v=0; v<=n; v++)
        pairV[v] = NIL;

    int rez = 0;

    /// cat timp avem cale alternativa
    while ( bfs() ){
        /// cautam nod liber
        for (int u=1; u<=m; u++)
            /// nod liber + cale alternativa de la el
            if (pairU[u]==NIL && dfs(u))
                rez++;
    }
    return rez;
}



void muchie(int u, int v) {
    adj[u].push_back(v);
}



int main()
{

    in>>m>>n;

    int nrmuchii;
    in>>nrmuchii;

    for(int i=1; i<=nrmuchii; i++){
        int x, y;
        in>>x>>y;
        muchie(x, y);
    }

    int rezultat = maxMatch();

    out<<rezultat<<'\n';

    for(int i=1; i<=m; i++){
        if( pairU[i] != NIL ){
            out<<i<<' '<<pairU[i]<<'\n';
        }
    }

    return 0;
}