Cod sursa(job #2900973)

Utilizator ptudortudor P ptudor Data 12 mai 2022 17:46:41
Problema Flux maxim de cost minim Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.84 kb
#include <bits/stdc++.h>

#define int long long

using namespace std;
#ifdef LOCAL
ifstream in("in.in");
ofstream out("out.out");
#else
ifstream in("fmcm.in");
ofstream out("fmcm.out");
#endif
const int nmax = 1005;
int n,m,cap[nmax][nmax],s,d,flow[nmax][nmax],cost[nmax][nmax],total_cost = 0;
vector<int> dis;
vector<vector<pair<int,int>>> g;
const int inf = 1000000005;

void bellmanford() {
    priority_queue<pair<int,int>> q;
    q.push({0 , s});
    dis = vector<int>(n + 1, inf); /// to find the min cost path
    dis[s] = 0;

    while(!q.empty()) {
        int val = -q.top().first;
        int node = q.top().second;
        q.pop();

        if (val > dis[node]) continue;

        for (auto k: g[node]) {
            if (dis[k.first] > dis[node] + k.second && flow[node][k.first] < cap[node][k.first]) {
                dis[k.first] = dis[node] + k.second;
                q.push({-dis[k.first], k.first});
            }
        }
    }
}


int find_augmenting_path() {
    priority_queue<pair<int,int>> q;
    q.push({0 , s});
    vector<int> myDis(n + 1, inf); /// to find the min cost path
    myDis[s] = 0;

    vector<int> path(n + 1, 0);

    while(!q.empty()) {
        int val = -q.top().first;
        int node = q.top().second;
        q.pop();

        if (val > myDis[node]) continue;

        dis[node] = dis[node] + myDis[node];

        for (auto k : g[node]) {
            int costEdge = cost[node][k.first] + dis[node] - dis[k.first];

            if (myDis[k.first] > myDis[node] + costEdge && flow[node][k.first] < cap[node][k.first]) {
                myDis[k.first] = myDis[node] + costEdge;
                path[k.first] = node;
                q.push({-myDis[k.first] , k.first});
            }
        }
    }

    if (path[d] == 0) {
        return -1;
    }

    int node = d,bottle_neck = inf;

    while(node != s) {
        int from = path[node];
        bottle_neck = min(bottle_neck , cap[from][node] - flow[from][node]);
        node = from;
    }

    node = d;
    while(node != s) {
        int from = path[node];
        flow[from][node] += bottle_neck;
        flow[node][from] -= bottle_neck;
        total_cost += (cost[from][node]) * bottle_neck;
        node = from;
    }

    return bottle_neck;
}
int maxflow() {
    int total_flow = 0;

    while(true) {
        int added_flow = find_augmenting_path();
        if (added_flow == -1) {
            return total_flow;
        }

        total_flow += added_flow;
    }
}
int32_t main() {
    in >> n >> m >> s >> d;

    g.resize(n + 1);
    for (int i = 1; i <= m; i++) {
        int u,v,capacity,this_cost;
        in >> u >> v >> capacity >> this_cost;
        g[u].push_back({v, this_cost});
        g[v].push_back({u , -this_cost});
        cap[u][v] = capacity;
        cost[u][v] = this_cost;
        cost[v][u] = -this_cost;
    }

    bellmanford();

    maxflow();
    out << total_cost << "\n";
}