Cod sursa(job #2890665)

Utilizator toma_ariciuAriciu Toma toma_ariciu Data 16 aprilie 2022 11:42:56
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.8 kb
#include <fstream>
#include <iostream>
#include <queue>
#include <vector>

using namespace std;

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

const int maxN = 355, inf = 0x3f3f3f3f;
int n, m, sursa, dest, flux[maxN][maxN], cap[maxN][maxN], cost[maxN], dist[maxN], p[maxN], total_cost, new_dist[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_ford(int start)
{
    for(int i = 1; i <= n; i++)
        new_dist[i] = inf;
    new_dist[start] = 0;
    q.push(start);
    while(!q.empty())
    {
        int curr = q.front();
        q.pop();
        /// fara conditia de ciclu negativ ca nu avem
        for(heapNode nxt : G[curr])
        {
            if(cap[curr][nxt.nod] == 0 || new_dist[curr] + nxt.cost >= new_dist[nxt.nod])
                continue;
            new_dist[nxt.nod] = new_dist[curr] + nxt.cost;
            q.push(nxt.nod);
        }
    }
}

bool dijkstra()
{
    for(int i = 1; i <= n; i++)
    {
        cost[i] = inf;
        dist[i] = new_dist[i];
        used[i] = 0;
    }
    while(!heap.empty())
        heap.pop();
    cost[sursa] = 0;
    new_dist[sursa] = 0;
    heap.push({sursa, 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(flux[curr.nod][nxt.nod] < cap[curr.nod][nxt.nod] && cost[curr.nod] + nxt.cost + dist[curr.nod] - dist[nxt.nod] < cost[nxt.nod])
            {
                p[nxt.nod] = curr.nod;
                cost[nxt.nod] = cost[curr.nod] + nxt.cost + dist[curr.nod] - dist[nxt.nod];
                new_dist[nxt.nod] = new_dist[curr.nod] + nxt.cost;
                heap.push({nxt.nod, cost[nxt.nod]});
            }
        }
    }
    if(cost[dest] == inf)
        return 0;
    return 1;
}

int main()
{
    fin >> n >> m >> sursa >> dest;
    for(int i = 1; i <= m; i++)
    {
        int x, y, c, cc;
        fin >> x >> y >> c >> cc;
        G[x].push_back({y, cc});
        G[y].push_back({x, -cc});
        cap[x][y] = c;
    }
    bellman_ford(sursa);
    while(dijkstra())
    {
        int min_flow = inf;
        for(int x = dest; x != sursa; x = p[x])
            min_flow = min(min_flow, cap[p[x]][x] - flux[p[x]][x]);
        for(int x = dest; x != sursa; x = p[x])
        {
            flux[p[x]][x] += min_flow;
            flux[x][p[x]] -= min_flow;
        }
        total_cost += min_flow * new_dist[dest];
        //cout << total_cost << ' ';
    }
    fout << total_cost;
    return 0;
}