Cod sursa(job #1771850)

Utilizator Cristian1997Vintur Cristian Cristian1997 Data 6 octombrie 2016 08:51:11
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.78 kb
#include <fstream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#include <bitset>
#include <queue>
#include <functional>
using namespace std;
using ll = long long;
using uint = unsigned int;
using ull = unsigned long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
#define INF 1000000000
#define NMAX 351

int n;
int f[NMAX][NMAX], c[NMAX][NMAX], cost[NMAX][NMAX];
int old_d[NMAX], d[NMAX], pred[NMAX];
bitset<NMAX> inQ;
vector<int> G[NMAX];

void bellman_ford(int);
bool dijkstra(int, int);

int main()
{
	int i, m, S, T;
	ifstream fin("fmcm.in");
	ofstream fout("fmcm.out");

    fin >> n >> m >> S >> T;

    for (i = 1; i <= m; ++i)
    {
        int a, b, y, z;
        fin >> a >> b >> y >> z;

        G[a].push_back(b);
        G[b].push_back(a);

        c[a][b] = y;
        cost[a][b] = z;

        c[b][a] = 0;
        cost[b][a] = -z;
    }

    bellman_ford(S);

    int flowCost, minf, node;
    for (flowCost = 0; dijkstra(S, T); )
    {
        for (minf = -1, node = T; node != S; node = pred[node])
        {
            if (minf == -1 || minf > c[pred[node]][node] - f[pred[node]][node])
                minf = c[pred[node]][node] - f[pred[node]][node];
        }

        for (node = T; node != S; node = pred[node])
        {
            flowCost += minf * cost[pred[node]][node];
            f[pred[node]][node] += minf;
            f[node][pred[node]] -= minf;
        }
    }

    fout << flowCost << '\n';

	fin.close();
	fout.close();

	return 0;
}


void bellman_ford(int v)
{
    queue<int> Q;
    fill(old_d, old_d + NMAX, INF);
    inQ.reset();

    old_d[v] = 0;
    for (Q.push(v), inQ[v] = true; !Q.empty(); Q.pop())
    {
        v = Q.front();
        inQ[v] = false;

        for (const auto &to : G[v])
        {
            if (c[v][to] > 0 && old_d[v] + cost[v][to] < old_d[to])
            {
                old_d[to] = old_d[v] + cost[v][to];
                
                if (!inQ[to]) Q.push(to), inQ[to] = true;
            }
        }
    }
}

bool dijkstra(int v, int T)
{
    priority_queue<pii, vector<pii>, greater<pii>> Q;
    fill(d, d + NMAX, INF);

    d[v] = 0;
    for (Q.emplace(0, v); !Q.empty(); )
    {
        auto aux = Q.top(); Q.pop();
        if (aux.first != d[aux.second]) continue;

        v = aux.second;
        for (const auto &to : G[v])
        {
            if (f[v][to] >= c[v][to]) continue;

            int edgeCost = cost[v][to] + old_d[v] - old_d[to];
            if (d[v] + edgeCost < d[to])
            {
                pred[to] = v;
                d[to] = d[v] + edgeCost;
                Q.emplace(d[to], to);
            }
        }
    }

    return d[T] != INF;
}