Cod sursa(job #2225625)

Utilizator akaprosAna Kapros akapros Data 27 iulie 2018 18:39:08
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.76 kb
#include <bits/stdc++.h>
#define inf 0x7fffffff

FILE *fin = freopen("fmcm.in", "r", stdin);
FILE *fout = freopen("fmcm.out", "w", stdout);

using namespace std;
class Graph
{
    int V;
    int *par, **r, **Cost, *d;
    list< int > *adj;
public:
    Graph(int V);

    void DEP(int S);
    void addEdge(int u, int v, int cap, int cost);
    int minCostmaxFlow(int S, int D);

};
Graph::Graph(int V)
{
    this->V = V;
    adj = new list <int> [V];
    par = new int [V];
    d = new int[V];
    r = new int *[V];
    Cost = new int*[V];

    for (int i = 0; i < V; ++ i)
    {
        r[i] = new int[V];
        Cost[i] = new int[V];

        for (int j = 0; j < V; ++ j)
            Cost[i][j] = r[i][j] = 0;
    }
}


void Graph::addEdge(int u, int v, int cap, int cost)
{
    r[u][v] = cap;
    adj[u].push_back(v);
    adj[v].push_back(u);
    Cost[u][v] = cost;
    Cost[v][u] = -cost;
}
void Graph::DEP(int s)
{
    for (int u = 0; u < V; ++ u)
    {
        d[u] = inf;
        par[u] = -1;
    }
    par[s] = s;
    d[s] = 0;

    vector <int> m(V, 2);
    deque <int> q;
    q.push_back(s);
    while (!q.empty())
    {
        int u = q.front();

        q.pop_front();
        m[u] = 0;
        for (auto v : adj[u])
            if (r[u][v] > 0)
            {
                int w = Cost[u][v];
                if (d[v] > d[u] + w)
                {
                    d[v] = d[u] + w;
                    par[v] = u;
                    if (m[v] == 2)
                    {
                        m[v] = 1;
                        q.push_back(v);
                    }
                    else if (m[v] == 0)
                    {
                        m[v] = 1;
                        q.push_front(v);
                    }
                }
            }
    }
}

int Graph::minCostmaxFlow(int S, int D)
{
    int flow = 0, cost = 0;
    do
    {
        DEP(S);
        if (d[D] >= inf) return cost;
        int nod = D, cap = inf;
        while (nod != S)
        {
            cap = min(cap, r[par[nod]][nod]);
            nod = par[nod];
        }
        nod = D;
        cost += cap * d[D];
        flow += cap;
        while (nod != S)
        {
            r[par[nod]][nod] -= cap;
            r[nod][par[nod]] += cap;
            nod = par[nod];
        }
    }
    while (d[D] < inf);
    return cost;
}

int main()
{
    int n, m, S, D;
    scanf("%d%d%d%d", &n, &m, &S, &D);
    -- S;
    -- D;
    Graph g(n);
    for (int i = 1; i <= m; ++ i)
    {
        int u, v, cap, cost;
        scanf("%d%d%d%d", &u, &v, &cap, &cost);
        -- u;
        -- v;
        g.addEdge(u, v, cap, cost);
    }

    printf("%d\n", g.minCostmaxFlow(S, D));
    return 0;
}