Cod sursa(job #1537238)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 27 noiembrie 2015 02:22:00
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.3 kb
#include <bits/stdc++.h>

using namespace std;

const int MAX_N = 350 + 1;
const int MAX_M = 12500 + 1;
const int INF = numeric_limits<int>::max() / 2;
const int NIL = -1;

struct Edge
{
    int capacity;
    int cost;

    int nod;
    int urm;
};

Edge G[2 * MAX_M];
int head[MAX_N];

int dist[MAX_N];
int tata[MAX_N];
int pointer[MAX_N];

class comp
{
public:

    bool operator () (const int x, const int y) const
    {
        return dist[x] > dist[y];
    }
};

priority_queue<int, vector<int>, comp> Q;

int N, M;
int contor;

void addEdge(int x, int y, int cap, int cost)
{
    G[contor] = {cap, cost, y, head[x]};
    head[x] = contor++;
}

bool BellmanFord(int S, int T)
{
    for (int i = 1; i <= N; ++i)
    {
        tata[i] = 0;
        dist[i] = INF;
    }

    tata[S] = S;
    dist[S] = 0;

    Q.push(S);

    while (Q.empty() == false)
    {
        int node = Q.top();
        Q.pop();

        for (int p = head[node]; p != NIL; p = G[p].urm)
        {
            int son = G[p].nod;

            if (G[p].capacity > 0 && dist[son] > dist[node] + G[p].cost)
            {
                tata[son] = node;
                pointer[son] = p;
                dist[son] = dist[node] + G[p].cost;

                Q.push(son);
            }
        }
    }

    if (dist[T] == INF)
        return false;
    else
        return true;
}

int mcmf(int S, int T)
{
    int cost = 0;
    int flow = 0;

    while (BellmanFord(S, T))
    {
        int node = T;
        int minFlow = INF;

        while (node != S)
        {
            minFlow = min(minFlow, G[ pointer[node] ].capacity);
            node = tata[node];
        }

        node = T;

        while (node != S)
        {
            G[ pointer[node] ].capacity -= minFlow;
            G[ pointer[node] ^ 1 ].capacity += minFlow;
            node = tata[node];
        }

        flow += minFlow;
        cost += minFlow * dist[T];
    }

    return cost;
}

int main()
{
    ifstream in("fmcm.in");
    ofstream out("fmcm.out");

    ios_base::sync_with_stdio(false);

    int S, T;
    in >> N >> M >> S >> T;

    for (int i = 1; i <= N; ++i)
        head[i] = NIL;

    while (M--)
    {
        int x, y, cap, cost;
        in >> x >> y >> cap >> cost;

        addEdge(x, y, cap, cost);
        addEdge(y, x, 0, -cost);
    }

    out << mcmf(S, T) << "\n";

    return 0;
}