Cod sursa(job #2900863)

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

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});

    bool foundSome = false;

    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;



        for (auto k : g[node]) {
            int costEdge = cost[node][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 (node == d) {

            int bottle_neck = inf;
            while(node != s) {

                int from = path[node];

                bottle_neck = min(bottle_neck , cap[from][node] - flow[from][node]);

                node = from;

            }

            if (bottle_neck < inf && bottle_neck > 0) {

                foundSome = true;

                node = d;

                while (node != s) {

                    int from = path[node];

                    flow[from][node] += bottle_neck;

                    flow[node][from] -= bottle_neck;

                    total_cost += (cost[from][node] - dis[from] + dis[node]) * bottle_neck;

                    node = from;

                }

                myDis[node] = inf;

            }
        }

    }

    if (!foundSome) return -1;

    return 0;

}

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();



    for (int i = 1; i <= n; i++) {

        for (int j = 1; j <= n; j++) {

            cost[i][j] += dis[i] - dis[j];

        }

    }



    maxflow();

    out << total_cost << "\n";

}