Cod sursa(job #2960677)

Utilizator MoarcascosminMoarcas Cosmin Moarcascosmin Data 4 ianuarie 2023 20:08:05
Problema Cuplaj maxim in graf bipartit Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.46 kb
#include <iostream>
#include <vector>
#include <fstream>
#include <queue>

using namespace std;

int n, m, e, numarNoduri, cuplaj;
int sursa, destinatie;
int flux[100000][100000];
int tata[100000];

vector<vector<int>> vecini;

void Citire()
{
    ifstream f("cuplaj.in");

    int nod1, nod2;

    f >> n >> m >> e;

    numarNoduri = n + m + 1;

    // Nodul sursa va fi 0, iar nodul destiantie va fi n + m + 1
    destinatie = numarNoduri;

    vecini.resize(numarNoduri + 1);

    for(int i = 0; i < e; i++)
    {
        f >> nod1 >> nod2;

        // Pentru a nu avea noduri cu acelasi numar, nodurile din R vor fi reprezentate ca (n + nod2)
        nod2 += n;

        vecini[nod1].push_back(nod2);
        vecini[nod2].push_back(nod1);
    }
}

// Adaug nodul start si nodul final
void AdaugareNoduri()
{
    for(int nod = 1; nod <= n; nod++)
    {
        vecini[sursa].push_back(nod);
        vecini[nod].push_back(sursa);
    }

    for(int nod = n + 1; nod < numarNoduri; nod++)
    {
        vecini[nod].push_back(destinatie);
        vecini[destinatie].push_back(nod);
    }
}

int Bfs()
{
    vector<bool> vizitat(numarNoduri + 1, false);
    queue<int> coada;

    coada.push(sursa);
    vizitat[sursa] = true;

    while(!coada.empty())
    {
        int nodCurent = coada.front();
        coada.pop();

        if(nodCurent == destinatie)
            break;

        for(auto vecin : vecini[nodCurent])
        {
            if(!vizitat[vecin] && flux[nodCurent][vecin] != 1)
            {
                coada.push(vecin);
                vizitat[vecin] = true;
                tata[vecin] = nodCurent;
            }
        }
    }
    return (vizitat[destinatie] == true);
}

void ActualizareFlux()
{
    int nodCurent = destinatie;
    int nodVecin = tata[destinatie];

    while(nodCurent != sursa)
    {
        flux[nodCurent][nodVecin] -= 1;
        flux[nodVecin][nodCurent] += 1;

        nodCurent = nodVecin;
        nodVecin = tata[nodCurent];
    }
}

void DeterminareCuplajMaxim()
{
    while(Bfs())
    {   
        cuplaj++;
        ActualizareFlux();
    }
}

void Afisare()
{
    ofstream g("cuplaj.out");

    g << cuplaj << endl;
    for(int nod = 1; nod <= n; nod++)
    {
        for(int nodVecin = n + 1; nodVecin < numarNoduri; nodVecin++)
        {
            if(flux[nod][nodVecin])
                g << nod << ' ' << nodVecin - n << endl;
        }
    }
}

int main()
{
    Citire();
    AdaugareNoduri();
    DeterminareCuplajMaxim();
    Afisare();

    return 0;
}