Cod sursa(job #2072162)

Utilizator Tiberiu02Tiberiu Musat Tiberiu02 Data 21 noiembrie 2017 15:13:31
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.63 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

const int MAX_N = 350;
int cost[1 + MAX_N][1 + MAX_N];
int flow[1 + MAX_N][1 + MAX_N];
int rel_cost[1 + MAX_N][1 + MAX_N];
vector<int> edges[1 + MAX_N];

int dist[1 + MAX_N];
int rel_dist[1 + MAX_N];
int from[1 + MAX_N];
const int INF = 1e9;

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

    int n, m, S, D;
    fin >> n >> m >> S >> D;

    for ( int i = 0; i < m; i ++ ) {
        int u, v, c, z;
        fin >> u >> v >> c >> z;
        edges[u].push_back( v );
        edges[v].push_back( u );
        cost[u][v] = z;
        cost[v][u] = -z;
        flow[u][v] = c;
    }

    for ( int i = 1; i <= n; i ++ )
        if ( i != S )
            dist[i] = INF;

    queue<int> bellman;
    bellman.push( S );

    while ( bellman.size() ) {
        int u = bellman.front();
        bellman.pop();

        for ( int v : edges[u] )
            if ( flow[u][v] && dist[u] + cost[u][v] < dist[v] ) {
                dist[v] = dist[u] + cost[u][v];
                bellman.push( v );
            }
    }

    for ( int u = 1; u <= n; u ++ )
        for ( int v : edges[u] )
            rel_cost[u][v] = cost[u][v] - dist[v] + dist[u];

    int min_cost = 0, max_flow = 0;
    bool improve = true;
    do {
        for ( int i = 1; i <= n; i ++ )
            from[i] = 0;
        from[S] = -1;
        rel_dist[S] = 0;

        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> dijkstra;
        dijkstra.push( make_pair( 0, S ) );
        while ( dijkstra.size() && dijkstra.top().second != D ) {
            int u = dijkstra.top().second, z = dijkstra.top().first;
            dijkstra.pop();

            if ( z != rel_dist[u] )
                continue;

            for ( int v : edges[u] )
                if ( flow[u][v] > 0 && ( !from[v] || rel_dist[u] + rel_cost[u][v] < rel_dist[v] ) ) {
                    from[v] = u;
                    rel_dist[v] = rel_dist[u] + rel_cost[u][v];
                    dijkstra.push( make_pair( z + rel_cost[u][v], v ) );
                }
        }

        if ( dijkstra.size() ) {
            int f = 1e9, c = 0;
            for ( int i = D; i != S; i = from[i] ) {
                f = min( f, flow[from[i]][i] );
                c += cost[from[i]][i];
            }
            for ( int i = D; i != S; i = from[i] ) {
                flow[from[i]][i] -= f;
                flow[i][from[i]] += f;
            }
            min_cost += c * f;
            max_flow += f;
        } else
            improve = false;
    } while ( improve );

    fout << min_cost << endl;


    return 0;
}