Cod sursa(job #2470235)

Utilizator aZvezdaAtanas Dimitrov aZvezda Data 8 octombrie 2019 21:23:55
Problema Flux maxim de cost minim Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.72 kb
#include <bits/stdc++.h>
using namespace std;
//#pragma GCC optimize ("O3")
//#pragma GCC target ("sse4")
#define endl "\n"
#define pb push_back
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const ll mod = 1e9 + 7, inf = 1e18;

const ll MAX_N = 400;
struct Edge {
    ll to, cap, cost, f;
    Edge(ll to, ll cap, ll cost) : to(to), cap(cap), cost(cost), f(0) {}
    Edge() : to(0), cap(0), cost(0), f(0) {}
};

struct MinCost {
    vector<ll> g[MAX_N];
    ll used[MAX_N], p[MAX_N], s, t, n;
    ll dist[MAX_N], capa[MAX_N][MAX_N], mlloPush[MAX_N];
    vector<Edge> edges;
    MinCost(ll s, ll t, ll n) : s(s), t(t), n(n) {}
    void addEdge(ll a, ll b, ll cap, ll cost) {
        g[a].push_back(edges.size());
        edges.emplace_back(b, cap, cost);
        capa[a][b] = cap;
    }
    bool spfa() {
        deque<ll> d;
        for(ll i = 0; i <= n; i ++) {dist[i] = inf; p[i] = -1; used[i] = 0; mlloPush[i] = inf;}
        dist[s] = 0;
        used[s] = 1;
        d.push_back(s);
        while(!d.empty()) {
            ll curr = d.front(); d.pop_front();
            used[curr] = 2;
            for(auto nxt : g[curr]) {
                if(dist[curr] + edges[nxt].cost > dist[edges[nxt].to] || capa[curr][edges[nxt].to] == 0) {continue;}
                p[edges[nxt].to] = curr;
                dist[edges[nxt].to] = dist[curr] + edges[nxt].cost;
                mlloPush[edges[nxt].to] = min(mlloPush[curr],  capa[curr][edges[nxt].to]);
                if(used[edges[nxt].to] == 2) {
                    d.push_front(edges[nxt].to);
                    used[edges[nxt].to] = 1;
                } else if(used[edges[nxt].to] == 0) {
                    d.push_back(edges[nxt].to);
                    used[edges[nxt].to] = 1;
                }
            }
        }
        return dist[t] != inf;
    }
    ll MinCostFlow() {
        ll c = 0, f = 0;
        while(true) {
            if(!spfa()) {
                break;
            }
            c += dist[t] * mlloPush[t];
            f += mlloPush[t];
            ll curr = t;
            while(curr != s) {
                capa[p[curr]][curr] -= mlloPush[t];
                curr = p[curr];
            }
        }
        return c;
    }
};

int main() {
    //ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    ofstream myfile;
    myfile.open ("fmcm.out");
    ifstream myFileIn;
    myFileIn.open ("fmcm.in");
    ll n, m, s, t;
    myFileIn >> n >> m >> s >> t;
    MinCost mc(s, t, n + 1);
    for(ll i = 0; i < m; i ++) {
        ll a, b, c, f;
        myFileIn >> a >> b >> c >> f;
        mc.addEdge(a, b, c, f);
    }
    myfile << mc.MinCostFlow();
    return 0;
}