Cod sursa(job #2962734)

Utilizator AlexPascu007Pascu Ionut Alexandru AlexPascu007 Data 8 ianuarie 2023 23:47:17
Problema Cuplaj maxim in graf bipartit Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.12 kb
#include <bits/stdc++.h>
using namespace std;

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

struct muchie{
    int iesire, intrare, cap, index;
};
vector<muchie> muchii;
int n, m, e, x, y, fluxmax = 0;;
bitset<20010> f;
vector <int> t;
vector<vector<int>> graf;

bool bfs() {
    queue<int> q;
    t.clear();
    t.resize(n + m + 2);
    f.reset();
    q.push(0);
    f[0] = true;
    while (!q.empty()) {
        int nod = q.front();
        q.pop();
        for (int it : graf[nod]) {
            muchie muchie = muchii[it];
            if (!f[muchie.intrare] && muchie.cap > 0) {
                t[muchie.intrare] = it;
                q.push(muchie.intrare);
                f[muchie.intrare] = true;
            }
        }
    }
    return f[n + m + 1];
}

int main(){
    fin >> n >> m >> e;
    graf.resize(n + m + 2);
    for (int i = 1; i <= e; i++){
        fin >> x >> y;
        muchii.push_back({x, y + n, 1, 2 * i - 1});
        muchii.push_back({y + n, x, 0, 2 * i - 2});
        graf[y + n].push_back(2 * i - 1);
        graf[x].push_back(2 * i - 2);
    }

    int nrmuchii = int(muchii.size());
    // adaugam muchiile de la sursa la nodurile din partea stanga
    for (int i = 1; i <= n; i++){
        nrmuchii += 2;
        muchii.push_back({0, i, 1, nrmuchii - 1 });
        graf[i].push_back(nrmuchii - 1);
        muchii.push_back({i, 0, 0, nrmuchii - 2});
        graf[0].push_back(nrmuchii - 2);

    }
    // adaugam muchiile de la nodurile din partea dreapta la destinatie
    for (int i = n + 1; i < n + m + 2 - 1; i++){
        nrmuchii += 2;
        muchii.push_back({i, n + m + 1, 1, nrmuchii - 1 });
        graf[n + m + 1].push_back(nrmuchii - 1);
        muchii.push_back({n + m + 1, i, 0, nrmuchii - 2});
        graf[i].push_back(nrmuchii - 2);
    }
    // algoritmul Ford-Fulkerson pentru flux maxim
    while (bfs()){
        for (auto vecin : graf[n + m + 1]) {
            muchie muchie = muchii[vecin];
            if (f[muchie.intrare] && muchii[muchie.index].cap != 0) {
                int nod = n + m + 1;
                t[n + m + 1] = muchie.index;
                int fluxmin = INT_MAX;
                while (nod != 0){
                    if (fluxmin > muchii[t[nod]].cap)
                        fluxmin = muchii[t[nod]].cap;
                    nod = muchii[t[nod]].iesire;
                }

                nod = n + m + 1;
                while (nod != 0){
                    muchii[t[nod]].cap -= fluxmin;
                    muchii[muchii[t[nod]].index].cap += fluxmin;

                    nod = muchii[t[nod]].iesire;
                }
                fluxmax += fluxmin;
            }
        }
    }
    // fluxul maxim este egal cu cuplajul maxim
    fout << fluxmax << "\n";
    // afisam muchiile saturate, adica cele care fac parte din cuplajul maxim
    for (auto muchie : muchii){
        if (muchie.cap == 0 && muchie.iesire != 0 && muchie.intrare != n + m + 1 && muchie.iesire < muchie.intrare)
        {
            fout << muchie.iesire << " " << muchie.intrare - n << "\n";
        }
    }
    return 0;

}