Cod sursa(job #1397327)

Utilizator irimiecIrimie Catalin irimiec Data 23 martie 2015 13:39:16
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.18 kb
#include <bits/stdc++.h>

using namespace std;

#define     echo            cout <<
#define     mp              make_pair
#define     fs              first
#define     sc              second
#define     pob             pop_back
#define     pub             push_back
#define     eps             1E-7
#define     sz(a)           a.size()
#define     count_one       __builtin_popcount;
#define     count_onell     __builtin_popcountll;
#define     fastIO          ios_base::sync_with_stdio(false)
#define     PI              (acos(-1.0))
#define     linf            (1LL<<62)//>4e18
#define     inf             (0x7f7f7f7f)//>2e9

#define MAXN 512

#ifndef ONLINE_JUDGE
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
#endif

int n, m, s, d;
vector<int> vec[MAXN];
bitset<MAXN> viz;
bool bvalid = true;
int cap[MAXN][MAXN];
int flow[MAXN][MAXN];
int cost[MAXN][MAXN];
int dist[MAXN], fn[MAXN];
long long flux;

int od[MAXN], rd[MAXN];
priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > H;
inline bool dijkstra() {
    for(int i = 1; i <= n; ++i)
        od[i] = inf;
    od[s] = rd[s] = 0;
    H.push(mp(od[s], s));

    int nod, cnod;
    while(!H.empty()) {
        cnod = H.top().fs; nod = H.top().sc; H.pop();

        if(od[nod] != cnod)
            continue;
        for(auto it : vec[nod])
            if(cap[nod][it]) {
                int nd = od[nod] + cost[nod][it] + dist[nod] - dist[it];
                if(nd < od[it]) {
                    od[it] = nd;
                    rd[it] = rd[nod] + cost[nod][it];
                    fn[it] = nod;
                    H.push(mp(od[it], it));
                }
            }
    }
    for(int i = 1; i <= n; ++i)
        dist[i] = rd[i];

    if(od[d] == inf)
        return false;

    int minflow = inf, cst = 0;
    for(int nod = d; nod != s; nod = fn[nod]) {
        minflow = min(minflow, cap[fn[nod]][nod]);
        cst += cost[fn[nod]][nod];
    }

    flux += minflow * rd[d];

    for(int nod = d; nod != s; nod = fn[nod]) {
        cap[fn[nod]][nod] -= minflow;
        cap[nod][fn[nod]] += minflow;
    }

    return true;
}

inline bool bford() {
    int minflow;
    queue<int> Q;

    for(int i = 1; i <= n; ++i)
        dist[i] = inf, fn[i] = -1;

    viz.reset();

    int nod;
    for(Q.push(s), viz[s] = true, dist[s] = 0; !Q.empty(); Q.pop()) {
        nod = Q.front();
        viz[nod] = false;

        for(auto it : vec[nod]) if(cap[nod][it]) {
            if(dist[it] > dist[nod] + cost[nod][it]) {
                dist[it] = dist[nod] + cost[nod][it];
                if(!viz[it]) {
                    Q.push(it);
                    viz[it] = 1;
                }
            }
        }

    }

    if(dist[d] == inf)
        return false;

    return true;
}

int main() {
    fin >> n >> m >> s >> d;

    int x, y, z, c;
    for(int i = 0; i < m; ++i) {
        fin >> x >> y >> z >> c;
        vec[x].pub(y);
        vec[y].pub(x);
        cap[x][y] = z;
        cost[x][y] = c;
        cost[y][x] = -c;
    }

    bford();

    flux = 0;
    while(dijkstra());

    fout << flux;
    return 0;
}