Cod sursa(job #2901149)

Utilizator toma_ariciuAriciu Toma toma_ariciu Data 13 mai 2022 07:09:16
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.68 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <queue>

using namespace std;

const string filename = "fmcm";
ifstream fin(filename + ".in");
ofstream fout(filename + ".out");

const int maxN = 355, inf = 0x3f3f3f3f;
int total, n, m, s, d, cap[maxN][maxN], flux[maxN][maxN], cost[maxN], pred[maxN], dist[maxN], newdist[maxN];
bool used[maxN];
queue <int> q;
struct heapNode {
    int nod, cost;
    bool operator < (const heapNode &other) const
    {
        return cost > other.cost;
    }
};
priority_queue <heapNode> heap;
vector <heapNode> G[maxN];

void bellman()
{
    for(int i = 1; i <= n; i++)
        newdist[i] = inf;
    newdist[s] = 0;
    q.push(s);
    while(!q.empty())
    {
        int curr = q.front();
        q.pop();
        for(auto nxt : G[curr])
        {
            if(cap[curr][nxt.nod] == 0 || newdist[curr] + nxt.cost >= newdist[nxt.nod])
                continue;
            newdist[nxt.nod] = newdist[curr] + nxt.cost;
            q.push(nxt.nod);
        }
    }
}

bool dijkstra()
{
    for(int i = 1; i <= n; i++)
    {
        cost[i] = inf;
        dist[i] = newdist[i];
        used[i] = 0;
    }
    while(!heap.empty())
        heap.pop();
    cost[s] = 0;
    newdist[s] = 0;
    heap.push({s, 0});
    while(!heap.empty())
    {
        heapNode curr = heap.top();
        heap.pop();
        if(used[curr.nod])
            continue;
        used[curr.nod] = 1;
        for(heapNode nxt : G[curr.nod])
        {
            if(cap[curr.nod][nxt.nod] > flux[curr.nod][nxt.nod] && cost[curr.nod] + dist[curr.nod] + nxt.cost < cost[nxt.nod] + dist[nxt.nod])
            {
                pred[nxt.nod] = curr.nod;
                cost[nxt.nod] = cost[curr.nod] + nxt.cost + dist[curr.nod] - dist[nxt.nod];
                newdist[nxt.nod] = newdist[curr.nod] + nxt.cost;
                heap.push({nxt.nod, cost[nxt.nod]});
            }
        }
    }
    if(cost[d] == inf)
        return 0;
    return 1;
}

int main()
{
    fin >> n >> m >> s >> d;
    for(int i = 1; i <= m; i++)
    {
        int x, y, rcap, rcost;
        fin >> x >> y >> rcap >> rcost;
        G[x].push_back({y, rcost});
        G[y].push_back({x, -rcost});
        cap[x][y] = rcap;
    }
    bellman();
    while(dijkstra())
    {
        int minflux = inf;
        for(int x = d; x != s; x = pred[x])
            minflux = min(minflux, cap[pred[x]][x] - flux[pred[x]][x]);
        for(int x = d; x != s; x = pred[x])
        {
            flux[pred[x]][x] += minflux;
            flux[x][pred[x]] -= minflux;
        }
        total += minflux * newdist[d];
    }
    fout << total;
    return 0;
}