Cod sursa(job #1955735)

Utilizator bt.panteaPantea Beniamin bt.pantea Data 6 aprilie 2017 10:30:29
Problema Flux maxim de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 3.27 kb
// Flux Maxim.cpp : Defines the entry point for the console application.
//

#include "iostream"
#include "fstream"
#include "vector"
#include "map"
#include <bitset>
#include <set>
#include <cstring>
#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];

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

void UpdateFluxRezidual(const int & nod, const int & value, const int & source) {
    if (nod == source) return;
    flux[Father[nod]][nod] -= value;
    UpdateFluxRezidual(Father[nod], value, source);
}

inline bool BF(const int & source, const int & destination) {
    set < pair < int, pair < int, int > > > myset;
    bitset < NMAX > used;
    memset(Father, 0, sizeof(Father));
    myset.insert(make_pair(0, make_pair(source, source)));
    while (!myset.empty()) {
        pair < int , pair < int, int > > P = *myset.begin();
        int nod = P.second.first;
        Father[nod] = P.second.second;
        int cq = P.first;
        myset.erase(myset.begin());
        if(used[nod]) continue;
        used[nod] = 1;
        if (nod == destination) {
            continue;
        }
        for (int i = 0; i < a[nod].size(); i++) {
            int next = a[nod][i];
            if (flux[nod][next] > 0 && used[next] == 0) {
                myset.insert(make_pair(cq + cost[nod][next], make_pair(next, nod)));
            }
        }
    }
    if (Father[destination]) return true;
    return false;
}

int maxflow(const int & source, const int & destination)
{
    int flow = 0, costflow = 0;
    for (; BF(source, destination);) {
        int flowmin = INF;
        int costpartial = 0;
        for (int nod = destination; nod != source; nod = Father[nod])
        {
            flowmin = min(flowmin, flux[Father[nod]][nod]);
            costpartial += cost[Father[nod]][nod];
        }
        for (int nod = destination; nod != source; nod = Father[nod]){
            flux[Father[nod]][nod] -= flowmin;
            flux[nod][Father[nod]] += flowmin;
        }

        costflow += flowmin * costpartial;

        /*
        for (int i = 0; i < a[destination].size(); i++) {
            int nod = a[destination][i];
            if (flux[nod][destination] <= 0 || Father[nod] == 0) continue;
            Father[destination] = nod;
            int flowmin = INF;
            for (nod = destination; nod != source; nod = Father[nod])
                flowmin = min(flowmin, flux[Father[nod]][nod]);
            for (nod = destination; nod != source; nod = Father[nod]) {
                flux[Father[nod]][nod] -= flowmin;
                flux[nod][Father[nod]] += flowmin;
            }
            flow += flowmin;
        }
        */
    }
    return costflow;
}

int main()
{
    int source, destination;
    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;
    }
    g << maxflow(source, destination);
    return 0;
}