Cod sursa(job #2967404)

Utilizator ScoveargaIlie Andrei-Virgil Scovearga Data 19 ianuarie 2023 16:24:02
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.28 kb
#include<iostream>
#include<fstream>
#include<climits>
#include<vector>
#include<queue>

using namespace std;

int tati[351], dis[351], tati2[351], dis2[351], adiacenta[351][351], cost[351][351], n, m, inceput, sink;
vector <int> graf[351];
priority_queue<pair<int,int>> pq;
pair<int,int> aux;

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

int dijkstra(int inceput, int sink, int n)
{
    for(int i = 1; i <= n; ++i)
    {
        dis[i] = INT_MAX;
        tati[i] = 0;
    }

    pq.empty();
    pq.push({0, inceput});

    dis[inceput] = 0;
    tati[inceput] = -1;

    while(pq.size())
    {
       aux = pq.top();
       pq.pop();

       int distanta = -aux.first;
       int nod = aux.second;

       if(dis[nod] < distanta) continue;

       for(int urm : graf[nod])
       {
           if(adiacenta[nod][urm])
           {
               int distantaNoua = distanta + cost[nod][urm] + (tati2[nod] - tati2[urm]);
               if(dis[urm] > distantaNoua)
               {
                   dis[urm] = distantaNoua;
                   tati[urm] = nod;
                   dis2[urm] = dis2[nod] + cost[nod][urm];

                   pq.push({-distantaNoua, urm});
               }
           }
       }
    }
    for(int i = 1; i <= n; ++i)
        tati2[i] = dis2[i];

    return tati[sink];
}

int maxFlow(int inceput, int sink, int n)
{
    int flow = 0, cost = 0;

    while(dijkstra(inceput, sink, n))
    {
        int newFlow = INT_MAX, urm = sink;

        while(urm != inceput)
        {
            int nod = tati[urm];
            newFlow = min(adiacenta[nod][urm], newFlow);

            urm = nod;
        }

        urm = sink;

        while(urm != inceput)
        {
            int nod = tati[urm];
            adiacenta[nod][urm] -= newFlow;
            adiacenta[urm][nod] += newFlow;
            urm = nod;
        }
        flow += newFlow;

        cost += (newFlow * tati2[sink]);
    }
    return cost;
}

void citire()
{
    f>>n>>m>>inceput>>sink;

    for(int i = 1; i <= m; ++i)
    {
        int x, y, cap, costAux;

        f>>x>>y>>cap>>costAux;

        adiacenta[x][y] += cap;

        cost[x][y] += costAux;
        cost[y][x] -= costAux;

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

int main()
{
    citire();

    g<<maxFlow(inceput, sink, n);

    return 0;
}