Cod sursa(job #2107169)

Utilizator retrogradLucian Bicsi retrograd Data 16 ianuarie 2018 20:19:03
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.19 kb
#include <bits/stdc++.h>

using namespace std;

struct Flow {
    const int kInf = 1e9;
    struct Edge {
        int to, f, c, k;
        int res() { return c - f; }
    };
    vector<Edge> es;
    vector<vector<int>> G;
    long long cost;

    Flow(int n) : G(n), in(n), dist(n) {}

    void add_edge(int a, int b, int c, int k) {
        G[a].push_back(es.size());
        es.push_back(Edge{b, 0, c, k}); 
    }
    void AddEdge(int a, int b, int c, int k) {
        add_edge(a, b, c, k);
        add_edge(b, a, 0, -k);
    }

    int start, aug;
    vector<int> in;
    vector<long long> dist;

    int dfs(int node, int f) {
        if (in[node]) {
            start = node; 
            aug = f;
            return 1;
        }

        in[node] = true;
        for (auto ei : G[node]) {
            auto& e = es[ei];
            if (dist[e.to] <= dist[node] + e.k or e.res() == 0)
                continue;

            dist[e.to] = dist[node] + e.k;
            
            int rec = dfs(e.to, min(f, e.res()));
            if (rec == 2) return 2;
            if (rec == 1) {
                es[ei].f += aug; es[ei ^ 1].f -= aug;
                cost += 1LL * aug * es[ei].k;
                return 1 + (node == start);
            }
        }
        in[node] = false;
        return 0;
    }
    
    bool iterate(int s) {
        bool ok = false;    
        //for (int s = 0; s < n; ++s) {
            fill(in.begin(), in.end(), 0);
            fill(dist.begin(), dist.end(), 1LL * kInf * kInf); 
            dist[s] = 0;
            ok |= dfs(s, kInf);
        //}
        return ok; 
    }
    pair<int, int> Solve(int s, int t) {
        AddEdge(t, s, kInf, -kInf);
        while (iterate(s));
        int flow = es[G[t].back()].f;
        cost += 1LL * flow * kInf;
        return make_pair(flow, cost);
    }

};

int main() {
    ifstream cin("fmcm.in");
    ofstream cout("fmcm.out");
    
    int n, m, s, t; 
    cin >> n >> m >> s >> t;
    --s; --t;

    Flow f(n);
    while (m--) {
        int a, b, c, k; 
        cin >> a >> b >> c >> k;
        f.AddEdge(a - 1, b - 1, c, k);
    }

    auto ret = f.Solve(s, t);
    cerr << ret.first << " " << ret.second << endl;
    cout << ret.second << endl;

    return 0;
}