Cod sursa(job #2960259)

Utilizator ioanatcioana t ioanatc Data 3 ianuarie 2023 21:17:19
Problema Cuplaj maxim in graf bipartit Scor 8
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.29 kb
#include<iostream>
#include<fstream>
#include<queue>
using namespace std;
#define Max 20000

int N, M, E, x, y, cuplaj;

bool graf_rez[Max][Max];
bool vizitat[Max];
int tata[Max];
int grad[Max];
auto comp_grad = [](int i, int j) {return grad[i] > grad[j]; };

void citesteDate();
void scrieRezultat();

void lantBFS(){
    // initializare date
    for(int i = 0; i <= N+M+1; i++)
        vizitat[i] = tata[i] = 0;

    priority_queue<int, vector<int>, decltype(comp_grad)> coada (comp_grad);

    coada.push(0);
    vizitat[0] = 1;

    while(!coada.empty()){
        int curent = coada.top();
        coada.pop();

        if(curent > N) continue;

        for(int nod = 1; nod <= N+M+1; nod++){
            if(!vizitat[nod] && graf_rez[curent][nod] > 0){

                vizitat[nod] = 1;
                tata[nod] = curent;
                coada.push(nod);
            }
        }
    }
}
int main(){
    citesteDate();
    
    // construiesc reteaua de transport
    for(int nod = 1; nod <= N; nod ++)
        graf_rez[0][nod] = 1;

    for(int nod = 1; nod <=M; nod ++)
        graf_rez[N + nod][N+M+1] = 1;
    // for(int i=0; i<=M+N+1; i++){
    //     for(int j=0; j<=M+N+1; j++)
    //         cout<<graf_rez[i][j]<<" ";
    //     cout<<endl;
    //}
    lantBFS();
    for(int nod = 1; nod < N+M+1; nod ++){

        if(vizitat[nod] && graf_rez[nod][N+M+1] > 0){
            // actualizam tatal nodului N+M+1(final) in lantul curent
            tata[N+M+1] = nod;
            // inregistram lantul curent in graful rezidual
            int auxiliar = N+M+1;

            while(tata[auxiliar]){

                graf_rez[ tata[auxiliar] ][ auxiliar ] -= 1;
                graf_rez[ auxiliar ][ tata[auxiliar] ] += 1;
                
                auxiliar = tata[auxiliar];
            }
            cuplaj+=1;
        }
    }

    scrieRezultat();
    return 0;
}
void citesteDate(){
    ifstream f("cuplaj.in");
    
    f>>N>>M>>E;
    while(f>>x>>y){
        graf_rez[x][N+y] = 1;
        grad[x]++;
    }
}
void scrieRezultat(){
    ofstream g ("cuplaj.out");
    g<<cuplaj<<"\n";

    for(int i = 1; i<=N; i++){
        for(int j = N+1; j<=M+N; j++)
            if(graf_rez[j][i])
                g<<i<<" "<<j-N<<"\n";
    }
}