Cod sursa(job #2960614)

Utilizator raskyNichita Sincarenco rasky Data 4 ianuarie 2023 19:14:19
Problema Cuplaj maxim in graf bipartit Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.21 kb
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;

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

vector<int> adjList[20001];
bool visited[20001];
int tati[20001];

bool formPair(int nod)
{
    visited[nod] = true;
    for(int nodAdiacent : adjList[nod])
    {
        // daca nodul din lista de adiacenta nu are tata, adica nu a fost conectat, atunci formam perechea
        if(tati[nodAdiacent] == 0)
        {
            tati[nod] = nodAdiacent;
            tati[nodAdiacent] = nod;
            return true;
        }

        // incercam sa formam alta pereche cu nodul adiacent al nodului fara pereche, in cazul in care nodul tata al nodului adiacent nu este vizitat a doua oara
        // se poate intra in acest if doar la a doua parcurgere, dupa ce se resteaza vectorul de vizitati (linia 65)
        if(visited[tati[nodAdiacent]]==false && formPair(tati[nodAdiacent]))            
        {
            tati[nod] = nodAdiacent;
            tati[nodAdiacent] = nod;
            return true;
        }
    }
    return false;
}

int main()
{
    int N, M, E, nr = 0;
    fcin>>N>>M>>E;
    int x, y;
    for(int i = 0; i < E; i++)
    {
        fcin>>x>>y;
        y += N;                         // adunam cu cate noduri avem in multimea initiala, ca sa facem diferenta
                                        // (adica sa nu avem doua noduri cu valoarea 1 de ex)
        adjList[x].push_back(y);
    }

    int loop = true;
    
    while(loop == true)
    {
        loop = false;
        for(int i = 1; i <= N; i++)
            // daca nodul nu a fost vizitat si nu are tata (adica nodul inca nu a fost conectat)
            // incercam sa formam perechea
            if(!visited[i] && !tati[i] && formPair(i))
            {
                nr++;
                loop = true;
            }
        // resetam vectorul de vizitati pentru a mai incerca o data formarea perechilor pentru nodurile care au ramas fara tata
        for(int i = 1; i <= N + M; i++)
            visited[i] = false;
    }

    fcout << nr << '\n';
    for(int i = 1; i <= N; i++)
        if(tati[i] != 0)
            fcout << i << " " << tati[i] << '\n';
    return 0;
}