Cod sursa(job #2968283)

Utilizator woodyinhoStoica Elias-Valeriu woodyinho Data 20 ianuarie 2023 21:25:19
Problema Flux maxim de cost minim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.09 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <climits>

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

int n,m,sursa,dest;
vector<vector<int>> graf; // lista de adiacenta
int cap[351][351], pret[351][351];
int tata[351];
int pretB[351], pretD[351], cost[351]; // pretul in urma algoritmului Bellman-Ford, Djikstra si costul minim al unui drum
int flux_min;

void bellmanFord()
{
    queue<int>coada;
    vector<bool>viz;
    viz.resize(n+1, false);
    viz[sursa]=true;
    pretB[sursa]=0;
    coada.push(sursa);

    while (!coada.empty())
    {
        int nod=coada.front();
        coada.pop();
        viz[nod] = false;
        for (int i = 0; i < graf[nod].size(); i++)
        {
            int vec = graf[nod][i];
            int pret_vecin = pret[nod][vec];
            if(cap[nod][vec] > 0 && pretB[vec] > pretB[nod] + pret_vecin)
            {
                pretB[vec] = pretB[nod] + pret_vecin;
                if(!viz[vec])
                {
                    viz[vec] = true;
                    coada.push(vec);
                }
            }
        }
    }
}

bool dijkstra ()
{
    priority_queue <pair <int, int>, vector <pair <int, int>>, greater <>> coada;

    for (int i = 1; i <= n; i++)
        pretD[i] = 1e9;

    pretD[sursa]=0;
    cost[sursa]=0;
    coada.emplace(0, sursa);

    while(!coada.empty())
    {
        pair<int,int> pereche_curenta = coada.top();
        coada.pop();
        int nod_curent = pereche_curenta.second;
        if(pretD[nod_curent] == pereche_curenta.first)
        {
            for(int i = 0; i < graf[nod_curent].size(); i++)
            {
                int vecin = graf[nod_curent][i];
                int pret_vecin = pret[nod_curent][vecin];
                if(cap[nod_curent][vecin] > 0 && pretD[vecin] > pretD[nod_curent] + pret_vecin + pretB[nod_curent] - pretB[vecin])
                {
                    pretD[vecin] = pretD[nod_curent] + pret_vecin + pretB[nod_curent] - pretB[vecin];
                    tata[vecin] = nod_curent;
                    cost[vecin] = min(cost[nod_curent], cap[nod_curent][vecin]);
                    coada.emplace(pretD[vecin], vecin);
                }
            }
        }
    }

    for (int i=1; i<=n; i++)
        pretB[i]=cost[i];

    if(pretD[dest] == 1e9)
        return false;

    int flux_curent = 1e9;
    int aux=dest;

    while (aux != sursa)
    {
        flux_curent = min(flux_curent, cap[tata[aux]][aux]);
        aux = tata[aux];
    }

    aux = dest;

    while (aux != sursa)
    {
        cap[tata[aux]][aux] -= flux_curent;
        cap[aux][tata[aux]] += flux_curent;
        aux = tata[aux];
    }

    flux_min+= flux_curent * cost[dest];
    return true;
}

int main()
{
    f >> n >> m >> sursa >> dest;
    graf.resize(n + 1);

    for(int i=1;i<=m;i++)
    {
        int x,y,c,z;
        f>>x>>y>>c>>z;

        graf[x].push_back(y);
        graf[y].push_back(x);

        cap[x][y]=c;
        pret[x][y]=z;
        pret[y][x]=-z;
    }

    bellmanFord();
    int rasp = dijkstra();
    while(rasp)
        rasp = dijkstra();

    g<<flux_min;

    return 0;
}