Cod sursa(job #1451003)

Utilizator klamathixMihai Calancea klamathix Data 15 iunie 2015 18:10:31
Problema Flux maxim de cost minim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.87 kb
#include <bits/stdc++.h>
using namespace std;
#define VI vector<int>
#define PII pair<int, int>
#define int long long

class Graph {
    public: 
    
    Graph(int n) {
        _N = n;
        _G = vector<VI> (n, vector<int> ());
        _cap = vector<VI> (n, vector<int> (n, 0));
        _cost = vector<VI> (n, vector<int> (n, 0));
    }

    void setSource(int source) {
        _source = source;
    }

    void setDest(int dest) {
        _dest = dest;
    }

    void addEdge(int x, int y, int cap, int cost = 0) {
        if(_cap[x][y]) {
            _cap[x][y] += cap;
            return;
        }

        _G[x].push_back(y);
        _G[y].push_back(x);
        _cap[x][y] = cap;
        _cost[x][y] = cost;
        _cost[y][x] = -cost;
    }

    bool augmentingPath(vector<int> &d, vector<int> &dad) {
        queue<int> Q;
        Q.push(_source);
        d[_source] = 0;
        dad[_source] = _source;
        vector<int> inQ(_N, 0);
        inQ[_source] = 1;

        while(!Q.empty()) {
            int node = Q.front();
            inQ[node] = 0;
            Q.pop();
            
            for(auto temp : _G[node]) {
                if(_cap[node][temp] <= 0)
                    continue;
                if(d[temp] > d[node] + _cost[node][temp]) {
                    dad[temp] = node;
                    d[temp] = d[node] + _cost[node][temp];
                    if(!inQ[temp]) {
                        Q.push(temp);
                        inQ[temp] = 1;
                    }
                }
            }
        }
        
        return (dad[_dest] != -1);
    }

    pair<int, int> minCostMaxFlow() {
        vector<int> dad(_N, -1);
        vector<int> d(_N, _COST_INF);
        
        int flow = 0;
        int flowcost = 0;

        while(augmentingPath(d, dad)) {
            int f = _CAP_INF;
            for(int node = _dest; node != _source; node = dad[node]) 
                f = min(f, _cap[dad[node]][node]);
            for(int node = _dest; node != _source; node = dad[node]) {
                _cap[dad[node]][node] -= f;
                _cap[node][dad[node]] += f;
            }
            flow += f;
            flowcost += f * d[_dest];
            dad = vector<int> (_N, -1);
            d = vector<int> (_N, _COST_INF);
        }
        
        return make_pair(flow, flowcost);
    }
    
    int _N;
    vector<VI> _G;
    vector<VI> _cap;
    vector<VI> _cost;
    int _source, _dest;
    static const int _CAP_INF = (1 << 30);
    static const int _COST_INF = (1 << 30);
};


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

    Graph G(n);

    for(int i = 0; i < m; ++i) {
        int a, b, c, cost; cin >> a >> b >> c >> cost;
        a--, b--;
        G.addEdge(a, b, c, cost);
    }

    G.setSource(s - 1);
    G.setDest(d - 1);
    
    int f = G.minCostMaxFlow().second;
    cout << f << "\n";
}