Cod sursa(job #1955917)

Utilizator bt.panteaPantea Beniamin bt.pantea Data 6 aprilie 2017 12:49:37
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.12 kb
#include "iostream"
#include "fstream"
#include "vector"
#include "map"
#include <bitset>
#include <set>
#include <cstring>
#include <queue>
#define NMAX 1005
#define INF 1000000000
using namespace std;
ifstream f("fmcm.in");
ofstream g("fmcm.out");
int flux[NMAX][NMAX], n, m;
int Father[NMAX], frezmin, MinFather[NMAX];
int bf[NMAX], cost[NMAX][NMAX];
vector < int > a[NMAX];
int source, destination;

inline int min(const int & a, const int & b) {
    if (a < b) return a;
    return b;
}

bitset < NMAX > inqueue;
int old[NMAX];
queue < int > Q;

inline void bellman()
{
    memset(old, 0x3f, sizeof(old));
    Q.push(source);
    old[source] = 0;
    inqueue[source] = 1;
    while (!Q.empty())
    {
        int nod = Q.front();
        inqueue[nod] = 0;
        Q.pop();
        for (int i = 0; i < a[nod].size(); i++) {
            int next = a[nod][i];
            if (flux[nod][next] > 0) {
                if (old[nod] + cost[nod][next] >= old[next]) continue;
                old[next] = old[nod] + cost[nod][next];
                if (inqueue[next]) continue;
                inqueue[next] = 1;
                Q.push(next);
            }
        }
    }
}

priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > H;
int d[NMAX], real_d[NMAX];

inline bool BF() {
    memset(d, 0x3f, sizeof(d));
    H.push(make_pair(0, source));
    d[source] = real_d[source] = 0;
    Father[destination] = 0;
    for (;!H.empty();) {
        int nod = H.top().second;
        int ncost = H.top().first;
        H.pop();
        if(d[nod] != ncost) continue;

        for (int i = 0; i < a[nod].size(); i++) {
            int next = a[nod][i];
            if (flux[nod][next] > 0) {
                int new_d = ncost + cost[nod][next] + old[nod] - old[next];
                if (new_d < d[next]) {
                    Father[next] = nod;
                    d[next] = new_d;
                    real_d[next] =  real_d[nod] + cost[nod][next];
                    //myset.insert(make_pair(d[next], next));
                    H.push(make_pair(d[next], next));
                }
            }
        }
    }
    memcpy(old, real_d, sizeof(d));



    if (Father[destination]) return true;
    return false;
}

int maxflow()
{
    int flow = 0, costflow = 0;
    for (; BF();) {
        int flowmin = INF;

        for (int nod = destination; nod != source; nod = Father[nod])
        {
            flowmin = min(flowmin, flux[Father[nod]][nod]);
        }
        for (int nod = destination; nod != source; nod = Father[nod]){
            flux[Father[nod]][nod] -= flowmin;
            flux[nod][Father[nod]] += flowmin;
        }

        costflow += flowmin * real_d[destination];
    }
    return costflow;
}

int main()
{
    f >> n >> m >> source >> destination;
    for (int i = 0; i < m; i++) {
        int x, y, fl, c;
        f >> x >> y >> fl >> c;
        a[x].push_back(y);
        a[y].push_back(x);
        flux[x][y] = fl;
        cost[x][y] = c;
        cost[y][x] = -c;
    }
    bellman();

    g << maxflow();
    return 0;
}