Cod sursa(job #2962374)

Utilizator NefelibataAnton Marius Alexandru Nefelibata Data 8 ianuarie 2023 14:37:04
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.19 kb
#include <bits/stdc++.h>
#include<climits>

using namespace std;

ifstream f ("fmcm.in");
ofstream o ("fmcm.out");
const int INF = INT_MAX;

int tata[360], d[360], old[360], dist_new[360];
int a[360][360], cost[360][360];

vector <int> g[360];

int dijkstra (int source, int sink, int n) {
    for(int i = 1; i <= n; ++i) {
        d[i] = INF;
        tata[i] = 0;
    }
    priority_queue <pair<int,int>> q;
    q.push({0, source});
    d[source] = 0;
    tata[source] = -1;

    while (q.size()) {
        pair <int,int> x = q.top();
        q.pop();
        int dist_node = -x.first;
        int node = x.second;
        if(d[node] < dist_node) continue;

        for(int to : g[node]) {
            if(a[node][to]) {
                int d_new = dist_node + cost[node][to] + (old[node] - old[to]);
                if(d[to] > d_new) {
                    d[to] = d_new;
                    tata[to] = node;
                    dist_new[to] = dist_new[node] + cost[node][to];
                    q.push({-d_new, to});
                }
            }
        }
    }

    for(int i = 1; i <= n; ++i) old[i] = dist_new[i];
    return tata[sink];
}

int maxFlowMinCost (int source, int sink, int n) {
    int flow = 0;
    int flowCost = 0;

    while(dijkstra(source, sink, n)) {
        int newFlow = INF;
        int to = sink;
        while(to != source) {
            int node = tata[to];
            newFlow = min(newFlow, a[node][to]);
            to = node;
        }

        to = sink;
        while(to != source) {
            int node = tata[to];

            a[node][to] -= newFlow;
            a[to][node] += newFlow;

            to = node;
        }
        flow += newFlow;
        flowCost += newFlow * old[sink];
    }
    return flowCost;
}

int main() {

    int n, m, source, sink;
    f>>n>>m>>source>>sink;

    for(int i = 1; i <= m; ++i) {
        int u, v, cap, cst;
        f >> u >> v >> cap >> cst;

        a[u][v] += cap;
        cost[u][v] += cst;
        cost[v][u] -= cst;

        g[u].push_back(v);
        g[v].push_back(u);
    }

    int flow = maxFlowMinCost(source, sink, n);

    o<<flow;

    return 0;
}