Cod sursa(job #2963745)

Utilizator allee69Aldea Alexia allee69 Data 11 ianuarie 2023 23:00:26
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.73 kb
#include <iostream>
#include <fstream>
#include <climits>
#include <vector>
#include <queue>

using namespace std;

ifstream f("fmcm.in");
ofstream g("fmcm.out");

int n, m, start, stop, flux_maxim;

vector<int>grefa[351];
vector<int>tata, viz, dist;

int capacitate[351][351], cost[351][351];
queue<int>q;

//vom folosi alg Bellman-Ford
int BF()
{
    viz.assign(n+1, 0);
    dist.assign(n+1, INT_MAX);

    while(!q.empty())
        q.pop();
    q.push(start);
    viz[start] = 1;
    tata[start] = start;

    dist[start] = 0;

    while(!q.empty())
    {
        int nod = q.front();
        q.pop();
        viz[nod] = 0; //il marchez ca nevizitat, deoarece l am scos din coada de parcurgere

        for(auto neighbour: grefa[nod])
        {
            if(capacitate[nod][neighbour] > 0 && dist[neighbour] > dist[nod] + cost[nod][neighbour])
            { //conditie flux + conditie bellman ford
                dist[neighbour] = dist[nod] + cost[nod][neighbour];
                tata[neighbour] = nod;

                if(!viz[neighbour])
                {
                    q.push(neighbour);
                    viz[neighbour] = 1;
                }
            }
        }
    }

    return dist[stop];
}

int main()
{
    f>>n>>m>>start>>stop;

    tata.assign(n+1, 0);

    int a, b, c, d;

    for(int i=0; i<m; i++)
    {
        f>>a>>b>>c>>d;
        grefa[a].push_back(b);
        grefa[b].push_back(a);

        capacitate[a][b] = c;
        cost[a][b] = d;
        cost[b][a] = -d;
    }

    while(true)
    {
        int total_cost = BF();
        if(total_cost == INT_MAX) break;
        int flow = INT_MAX;
        for(int nod = stop; nod != start; nod = tata[nod])
            flow = min(flow, capacitate[tata[nod]][nod]);

        for(int nod = stop; nod != start; nod = tata[nod])
        {
            capacitate[tata[nod]][nod] -= flow;
            capacitate[nod][tata[nod]] += flow;
        }
        flux_maxim += flow * total_cost;
    }
    g<<flux_maxim;
    return 0;
}
//complexitate O(n^2 * m^2)

//Vom folosi alg Bellman-Ford pentru a gasi flow-ul maxim de cost minim
//pentru un graf orientat
//Citim, apoi construim graful folosindu-ne de o lista de adiacenta.
//grefa -> pentru lista de adiacenta a grafului
//capacitate -> pentru capacitatea fiecarei muchii
//In subpr BF folosim alg BEllman-Ford pentru a calcula cel mai scurt drum
//de la start pana la stop, numarand si retinand costul fiecarei muchii
//prin care trece. Apoi, gaseste flow-ul minim de pe acest drum, updateaza
//capacitatile muchiilor corespunzator si tine minte costul total.
//Loopul while continua pana cand functia BF returneaza o valoare de tip
//INT_MAX, ce arata faptul ca nu mai exista niciun flow intre start si stop
//In output vom avea flow-ul maxim cu costul minim