Cod sursa(job #2601188)

Utilizator PetrescuAlexandru Petrescu Petrescu Data 13 aprilie 2020 23:33:15
Problema Flux maxim de cost minim Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.13 kb
#include <bits/stdc++.h>
#define MAX 1001
#define INF 2e9

using namespace std;

class Cmp
{
public:

    bool operator()(const pair<int, int> &A, const pair<int, int> &B)const {
        return A.second > B.second;
    }
};

int n, m, s, d;
int cap[MAX][MAX], flux[MAX][MAX];
int distBellman[MAX], dist[MAX];
int tata[MAX], viz[MAX];
vector<pair<int, int>>graph[MAX];
priority_queue<pair<int, int>, vector<pair<int, int>>, Cmp>PQ;

bool Dijkstra()
{
    while(PQ.size())PQ.pop();

    for(int i = 1; i <= n; i++)
    {
        tata[i] = viz[i] = 0;
        dist[i] = INF;
    }

    bool verif = 0;

    dist[s] = 0;
    PQ.push({s, 0});

    while(PQ.size())
    {
        int nod = PQ.top().first;
        int cost = PQ.top().second;

        PQ.pop();

        if(dist[nod] != cost)continue;
        if(nod == d)verif = 1;
        viz[nod] = 1;

        for(auto vecin : graph[nod])
            if(viz[vecin.first])continue;
            else if(cap[nod][vecin.first] > flux[nod][vecin.first] && dist[vecin.first] > dist[nod] + vecin.second)
            {
                tata[vecin.first] = nod;
                dist[vecin.first] = dist[nod] + vecin.second;
                PQ.push({vecin.first, dist[vecin.first]});
            }
    }

    return verif;
}

void BellmanFord()
{
    queue<int>Q;

    for(int i = 1; i <= n; i++)
        distBellman[i] = INF;

    distBellman[s] = 0;
    Q.push(s);

    while(Q.size())
    {
        int nod = Q.front();

        Q.pop();

        for(auto vecin : graph[nod])
            if(distBellman[vecin.first] > distBellman[nod] + vecin.second)
            {
                distBellman[vecin.first] = distBellman[nod] + vecin.second;
                Q.push(vecin.first);
            }
    }


    vector<pair<pair<int, int>, int>>edges;
    for(int nod = 1; nod <= n; ++nod)
    {
        for(auto &vecin : graph[nod])
        {
            vecin.second += distBellman[nod] - distBellman[vecin.first];
            edges.push_back({{nod, vecin.first}, vecin.second});
        }
    }

    for(auto edge : edges)
        graph[edge.first.second].push_back({edge.first.first, -edge.second});
}

int main()
{
    ifstream fin("fmcm.in");
    ofstream fout("fmcm.out");

    fin >> n >> m >> s >> d;

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

        fin >> x >> y >> c >> z;

        graph[x].push_back({y, z});
        cap[x][y] += c;
    }

    BellmanFord();

    int sol = 0;
    while(Dijkstra())
    {
        int nod = d;

        int minCap = INF;

        while(nod != s)
        {
            if(minCap > cap[tata[nod]][nod] - flux[tata[nod]][nod])
                minCap = cap[tata[nod]][nod] - flux[tata[nod]][nod];

            nod = tata[nod];
        }

        sol += minCap * (dist[d] + distBellman[d] - distBellman[s]);
        nod = d;

        while(nod != s)
        {
            flux[tata[nod]][nod] += minCap;
            flux[nod][tata[nod]] -= minCap;
            nod = tata[nod];
        }
    }

    fout << sol;

    fin.close();
    fout.close();

    return 0;
}