Cod sursa(job #2960298)

Utilizator mihneagherghelMihnea Gherghel-Butan mihneagherghel Data 3 ianuarie 2023 23:51:40
Problema Flux maxim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.74 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;

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

struct muchie {
    int nodStart, nodStop, capacitate,poz;
};

vector<vector<int>> listaAdiacenta;
vector<muchie> muchii;
muchie mc;
vector<bool> viz;
vector<int> tata;
int n, m, e, sursa, destinatie, numarNoduri, numarMuchii;

void adaugareMuchie(int a, int b)
{
    // adaugare arc direct
    listaAdiacenta[b].push_back(numarMuchii+1);
    mc.nodStart = a;
    mc.nodStop = b ;
    mc.capacitate = 1;
    mc.poz = numarMuchii+1;
    muchii.push_back(mc);
    // adaugare arc indirect 
    listaAdiacenta[a].push_back(numarMuchii);
    mc.nodStart = b ;
    mc.nodStop = a;
    mc.capacitate = 0;
    mc.poz = numarMuchii;
    muchii.push_back(mc);
    numarMuchii+=2;
}
// citesc datele din fisier si pe baza lor imi construies reteaua de transport asociata grafului bipartit
void citire()
{
    fin >> n >> m >> e;
    numarNoduri = n + m + 2;
    sursa = 0;
    destinatie = n + m + 1;
    listaAdiacenta = vector<vector<int>>(numarNoduri, vector<int>());
    int a, b;
    for (int i = 0; i < e; i++)
    {
        fin >> a >> b;
        adaugareMuchie(a, b + n);
    }
    for (int i = 1; i <= n; i++)
    {
        adaugareMuchie(sursa, i);
    }
    for (int i = n+1; i < numarNoduri-1; i++)
    {
        adaugareMuchie(i, destinatie);
    }
}
// functia care determina daca exista sau nu un lant nesaturat si daca exista il construieste
bool bfs()
{
    tata = vector<int>(numarNoduri, 0);
    viz = vector<bool>(numarNoduri, false);
    queue<int> coada;
    coada.push(sursa);
    viz[sursa] = true;
    while (!coada.empty())
    {
        int nod = coada.front();
        coada.pop();
        if (nod != destinatie)
        {
            for (auto index : listaAdiacenta[nod])
            {
                mc = muchii[index];
                if (viz[mc.nodStop] == false && mc.capacitate > 0)
                {
                    tata[mc.nodStop] = index;
                    coada.push(mc.nodStop);
                    viz[mc.nodStop] = true;
                }
            }
        }
    }
    return viz[destinatie];
}
int main()
{
    citire();
    int maxFlow = 0;
    while (bfs())
    {
        // parcurgem toate muchiile care pornesc din destinatie
        for (auto index : listaAdiacenta[destinatie])
        {
            if (viz[muchii[index].nodStop] && muchii[muchii[index].poz].capacitate > 0)
            {
                // stabilim care este muchia prin care am ajuns la destinatie
                int minFlow = 100000000;
                mc = muchii[index];
                tata[destinatie] = mc.poz;
                int nod = destinatie;
                // calculam capacitatea reziduala a lantului 
                while (nod != sursa)
                {
                    minFlow = min(minFlow, muchii[tata[nod]].capacitate);
                    nod = muchii[tata[nod]].nodStart;

                }
                // revizuire fluxuri
                nod = destinatie;
                while (nod != sursa)
                {
                    muchii[muchii[tata[nod]].poz].capacitate += minFlow;
                    muchii[tata[nod]].capacitate -= minFlow;
                    nod = muchii[tata[nod]].nodStart;
                }
                maxFlow += minFlow;
            }
        }
    }
    fout << maxFlow << endl;
    for (muchie mcc : muchii)
    {
        if (mcc.nodStart < mcc.nodStop && mcc.nodStart != 0 && mcc.nodStop != destinatie && mcc.capacitate == 0)
        {
            fout << mcc.nodStart << " " << mcc.nodStop - n << "\n";
        }
    }
    //complexitate O((n+m)^2*m)
}