Cod sursa(job #2030528)

Utilizator Alexa2001Alexa Tudose Alexa2001 Data 1 octombrie 2017 18:58:45
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.9 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin ("fmcm.in");
ofstream fout ("fmcm.out");

typedef pair<int,int> Pair;
const int Nmax = 355, inf = 1e9;

int n, m, S, D, x, y, cap, cost;

class floow
{
    int cost[Nmax][Nmax], cap[Nmax][Nmax], f[Nmax][Nmax], p[Nmax], dist[Nmax], t[Nmax], new_p[Nmax];
    vector<int> v[Nmax];
    bool InQueue[Nmax];
    priority_queue< Pair, vector< Pair >, greater< Pair > > heap;

    bool dijkstra()
    {
        for(int i=1; i<=n; ++i) dist[i] = inf, t[i] = 0;
        dist[S] = 0;
        heap.push({dist[S], S});

        while(heap.size())
        {
            int node = heap.top().second, nr = heap.top().first;
            heap.pop();
            if(dist[node] != nr) continue;

            for(auto it : v[node])
                if(f[node][it] < cap[node][it])
                {
                    int cc = dist[node] + cost[node][it] + p[node] - p[it];
                    if(dist[it] > cc)
                    {
                        t[it] = node;
                        dist[it] = cc;
                        heap.push({cc, it});

                        new_p[it] = new_p[node] + cost[node][it];
                    }
                }
        }

        for(int i=1; i<=n; ++i) p[i] = new_p[i];
        return dist[D] != inf;
    }

public:
    void prepare()
    {
        queue<int> q;
        q.push(S); p[S] = 0;

        while(q.size())
        {
            int node = q.front();
            q.pop();
            InQueue[node] = 0;

            for(auto it : v[node])
                if(f[node][it] < cap[node][it]  && p[it] > p[node] + cost[node][it])
                {
                    p[it] = p[node] + cost[node][it];
                    if(InQueue[it]) continue;
                    InQueue[it] = 1;
                    q.push(it);
                }
        }
    }

    int max_flow_min_cost()
    {
        int node, fmin, dad, cc, ans = 0;
        while(dijkstra())
        {
            node = D;
            fmin = inf;
            while(node != S)
            {
                dad = t[node];
                fmin = min(fmin, cap[dad][node] - f[dad][node]);
                node = dad;
            }

            ans += fmin * p[D];

            node = D;
            while(node != S)
            {
                dad = t[node];
                f[dad][node] += fmin;
                f[node][dad] -= fmin;
                node = dad;
            }
        }
        return ans;
    }

    void add_edge(int x, int y, int Cap, int Cost)
    {
        v[x].push_back(y);
        v[y].push_back(x);
        cap[x][y] = Cap, cap[y][x] = 0;
        cost[x][y] = Cost, cost[y][x] = -Cost;
        f[x][y] = f[y][x] = 0;
    }
} graph;

int main()
{
    fin >> n >> m >> S >> D;
    for(int i=1; i<=m; ++i)
    {
        fin >> x >> y >> cap >> cost;
        graph.add_edge(x, y, cap, cost);
    }

    graph.prepare();
    fout << graph.max_flow_min_cost() << '\n';

    return 0;
}