Cod sursa(job #2931172)

Utilizator toma_ariciuAriciu Toma toma_ariciu Data 30 octombrie 2022 17:03:40
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.82 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], fake_dist[maxN], real_dist[maxN], p[maxN], total_cost, 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++)
        dist[i] = inf;
    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 || dist[curr] + nxt.cost >= dist[nxt.nod])
                continue;
            dist[nxt.nod] = dist[curr] + nxt.cost;
            q.push(nxt.nod);
        }
    }
}

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