Cod sursa(job #1952057)

Utilizator Cristian1997Vintur Cristian Cristian1997 Data 3 aprilie 2017 22:06:20
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.7 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, flowCost, S, T;
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];
priority_queue<pii, vector<pii>, greater<pii>> priQ;
queue<int> Q;

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

int main()
{
	int i, m;
	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);

    for (flowCost = 0; dijkstra(S, T); );

    fout << flowCost << '\n';

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

	return 0;
}


void bellman_ford(int v)
{
    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] > f[v][to] && 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)
{
    int cst;
    fill(d, d + NMAX, INF);

    d[v] = 0;
    for (priQ.emplace(0, v); !priQ.empty(); )
    {
        v = priQ.top().second; cst = priQ.top().first;
        priQ.pop();

        if (cst != d[v]) continue;

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

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

    if(d[T] == INF) return false;

    int minf;
    for (cst = 0, minf = INF, v = T; v != S; v = pred[v])
    {
        if (minf > c[pred[v]][v] - f[pred[v]][v])
            minf = c[pred[v]][v] - f[pred[v]][v];
        cst += cost[pred[v]][v];
    }

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

    return true;
}