Cod sursa(job #2595127)

Utilizator Mihai145Oprea Mihai Adrian Mihai145 Data 7 aprilie 2020 10:30:47
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.79 kb
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

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

const int NMAX = 350;
const int INF = 1e9;

int N, M, S, D;

vector <int > g[NMAX + 2];
int capacity[NMAX + 2][NMAX + 2], cost[NMAX + 2][NMAX + 2], flow[NMAX + 2][NMAX + 2];
int bef[NMAX + 2];

int oldD[NMAX + 2], realD[NMAX + 2], d[NMAX + 2];

bool inQ[NMAX + 2];

queue <int > Q;
priority_queue <pair <int, int>, vector <pair <int, int>>, greater <pair <int, int>> > pq;

void Bellman()
{
    for(int i = 1; i <= N; i++)
        oldD[i] = INF;

    Q.push(S);
    oldD[S] = 0, inQ[S] = true;

    while(!Q.empty())
    {
        int node = Q.front();
        Q.pop();

        inQ[node] = false;

        for(auto it : g[node])
            if(flow[node][it] < capacity[node][it])
                if(oldD[it] > oldD[node] + cost[node][it])
                {
                    oldD[it] = oldD[node] + cost[node][it];

                    if(!inQ[it])
                    {
                        Q.push(it);
                        inQ[it] = true;
                    }
                }
    }
}

bool Dijkstra()
{
    for(int i = 1; i <= N; i++)
        d[i] = INF;

    pq.push({0, S});
    d[S] = realD[S] = 0;

    while(!pq.empty())
    {
        pair <int, int> current = pq.top();
        pq.pop();

        int node = current.second;
        int cst = current.first;

        if(d[node] != cst)
            continue;

        for(auto it : g[node])
            if(flow[node][it] < capacity[node][it])
            {
                int distToIt = d[node] + cost[node][it] + oldD[node] - oldD[it];

                if(distToIt < d[it])
                {
                    d[it] = distToIt;
                    realD[it] = realD[node] + cost[node][it];

                    bef[it] = node;

                    pq.push({d[it], it});
                }
            }
    }

    return (d[D] != INF);
}

int main()
{
    fin >> N >> M >> S >> D;

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

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

        capacity[x][y] = c;

        cost[x][y] = z;
        cost[y][x] = -cost[x][y];
    }

    int minCost = 0;

    Bellman();

    while(Dijkstra())
    {
        int pumpFlo = INF;

        for(int node = D; node != S; node = bef[node])
            pumpFlo = min(pumpFlo, capacity[bef[node]][node] - flow[bef[node]][node]);

        for(int node = D; node != S; node = bef[node])
        {
            flow[bef[node]][node] += pumpFlo;
            flow[node][bef[node]] -= pumpFlo;
        }

        minCost += pumpFlo * realD[D];
    }

    fout << minCost << '\n';

    return 0;
}