Cod sursa(job #2892231)

Utilizator LucaMihaiLM10Luca Ilie LucaMihaiLM10 Data 21 aprilie 2022 13:30:46
Problema Flux maxim de cost minim Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.26 kb
#include <bits/stdc++.h>

#define MAX_N 350
#define MULT (1 << 30)

using namespace std;

struct FLOW {
    struct elemPQ {
        int u, cost;

        bool operator < (const elemPQ &a) const {
            return cost > a.cost;
        }
    };

    int s, t, vt;
    bool inQ[MAX_N];
    int cap[MAX_N][MAX_N], cost[MAX_N][MAX_N], flux[MAX_N][MAX_N], parent[MAX_N], c[MAX_N], dist[MAX_N];
    vector <int> edges[MAX_N];

    void add_edge( int u, int v, int c, int z ) {
        edges[u].push_back( v );
        edges[v].push_back( u );
        cap[u][v] = c;
        cost[u][v] = z;
        cost[v][u] = -z;
    }

    void bellman() {
        int u;
        queue <int> q;

        for ( u = 0; u < vt; u++ )
            dist[u] = MULT;
        for ( u = 0; u < vt; u++ )
            inQ[u] = false;

        dist[s] = 0;
        q.push( s );
        while ( !q.empty() ) {
            u = q.front();
            q.pop();
            inQ[u] = false;

            for ( int v: edges[u] ) {
                if ( dist[u] + cost[u][v] < dist[v] && flux[u][v] < cap[u][v] ) {
                    parent[v] = u;
                    dist[v] = dist[u] + cost[u][v];
                    if ( !inQ[v] ) {
                        q.push( v );
                        inQ[v] = true;
                    }
                }
            }
        }
    }

    bool dijkstra() {
        int u;
        priority_queue <elemPQ> pq;

        for ( u = 0; u < vt; u++ )
            parent[u] = -1;
        for ( u = 0; u < vt; u++ )
            c[u] = MULT;

        c[s] = 0;
        pq.push( { s, 0 } );
        while ( !pq.empty() ) {
            u = pq.top().u;
            pq.pop();

            for ( int v: edges[u] ) {
                if ( c[u] + cost[u][v] + dist[v] - dist[u] < c[v] && flux[u][v] < cap[u][v] ) {
                    parent[v] = u;
                    c[v] = c[u] + cost[u][v] + dist[v] - dist[u];
                    pq.push( { v, c[v] } );
                }
            }
        }

        return c[t] != MULT;
    }

    int minCostmaxFlow() {
        int maxFlow, newFlow, minCost, newCost, v;

        bellman();

        maxFlow = 0;
        minCost = 0;
        while ( dijkstra() ) {
            newFlow = MULT;
            newCost = 0;
            v = t;
            while ( v != s ) {
                newFlow = min( newFlow, cap[parent[v]][v] - flux[parent[v]][v] );
                newCost += cost[parent[v]][v];
                v = parent[v];
            }

            maxFlow += newFlow;
            minCost += newFlow * newCost;
            v = t;
            while ( v != s ) {
                flux[parent[v]][v] += newFlow;
                flux[v][parent[v]] -= newFlow;
                v = parent[v];
            }
        }

        return minCost;
    }
};

FLOW flow;

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

    int n, m, s, t, u, v, c, z, i;

    cin >> n >> m >> s >> t;
    s--;
    t--;
    for ( i = 0; i < m; i++ ) {
        cin >> u >> v >> c >> z;
        u--;
        v--;
        flow.add_edge( u, v, c, z );
    }

    flow.s = s;
    flow.t = t;
    flow.vt = n;

    cout << flow.minCostmaxFlow();

    return 0;
}