Cod sursa(job #1537239)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 27 noiembrie 2015 02:24:20
Problema Flux maxim de cost minim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.4 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];

bool inQueue[MAX_N];
queue<int> 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;
        inQueue[i] = false;
    }

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

    Q.push(S);

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

        inQueue[node] = 0;

        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;

                if (!inQueue[son])
                {
                    inQueue[son] = true;
                    Q.push(son);
                }
            }
        }
    }

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

long long mcmf(int S, int T)
{
    long long 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 += 1LL * minFlow * dist[T];
    }

    return cost;
}

int main()
{
    FILE *in = fopen("fmcm.in", "r");
    FILE *out = fopen("fmcm.out", "w");

    int S, T;
    fscanf(in, "%d%d%d%d", &M, &M, &S, &T);

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

    while (M--)
    {
        int x, y, cap, cost;
        fscanf(in, "%d%d%d%d", &x, &y, &cap, &cost);

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

    fprintf(out, "%lld\n", mcmf(S, T));

    return 0;
}