Cod sursa(job #2958849)

Utilizator Katherine456719Swan Katherine Katherine456719 Data 28 decembrie 2022 16:59:51
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.81 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

using namespace std;
int noduri;
int n,m,e;
struct muchie{
    int start,end,cp,ind;
};
int sursa, destinatie;
vector<muchie> muchii;
vector<vector<int>> adj_list;
vector<int> parinti;
// pt nodul x retinem indicele muchiei cu care s-a ajuns la x
vector<bool> viz;
void adauga_muchie(int a, int b){
     int dim = (int)muchii.size();

     adj_list[a].push_back(dim);
     adj_list[b].push_back(dim + 1);

     muchii.push_back({a,b, 1,  dim + 1});
     muchii.push_back({b,a, 0,  dim});

}
bool gaseste_drum(){
    viz.clear();
    parinti.clear();
    viz.resize(noduri, false);
    parinti.resize(noduri);

    queue<int> q;
    viz[sursa] = true;
    q.push(sursa);
    while(!q.empty()){
        int node = q.front();
        q.pop();
        if(node != destinatie){
            for(int x : adj_list[node]){
                muchie curr_m = muchii[x];
                if(!viz[curr_m.end] and curr_m.cp != 0){
                    parinti[curr_m.end] = x;
                    q.push(curr_m.end);
                    viz[curr_m.end] = true;
                }
            }
        }
    }
    return viz[destinatie];
}
int main() {
    ifstream fin("cuplaj.in");
    ofstream fout("cuplaj.out");
    fin >> n >> m >> e;

    noduri = m + n + 2;
    sursa  = 0;
    destinatie = n + m + 1;
    adj_list.resize(noduri);
    while(e--){
        int x,y;
        fin >> x >> y;
        adauga_muchie(x,y + n);
    }

    for(int i = 1;i <= n; ++i){
       adauga_muchie(sursa,i);
    }
    for(int j = n + 1; j <= n + m; ++j) {
        adauga_muchie(j,destinatie);
    }
    int ans = 0;
    while(gaseste_drum()){
        for(int x : adj_list[destinatie]){
            if(viz[muchii[x].end] and muchii[muchii[x].ind].cp != 0){
                //muchie reziduala
                muchie curr_m = muchii[x];
                //indicele muchiei din graf
                parinti[destinatie] = curr_m.ind;
                int flux = 99999999;
                int node = destinatie;
                while(node != sursa){
                    flux = min(flux,muchii[parinti[node]].cp);
                    node = muchii[parinti[node]].start;
                }

                node = destinatie;
                while(node != sursa){
                    muchii[parinti[node]].cp -= flux;
                    muchii[muchii[parinti[node]].ind].cp += flux;
                    node = muchii[parinti[node]].start;
                }
                ans += flux;
            }
        }
    }
    fout << ans <<"\n";
    for(auto x: muchii){
        if(x.start < x.end and x.start != sursa and x.end != destinatie and x.cp == 0){
            fout << x.start << " " << x.end-n <<"\n";
        }
    }
    return 0;
}