Cod sursa(job #2836286)

Utilizator Tudor06MusatTudor Tudor06 Data 20 ianuarie 2022 00:47:32
Problema Flux maxim de cost minim Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.82 kb
#include <bits/stdc++.h>

using namespace std;

const int NMAX = 350;
const int INF = 2e9;

vector <int> edges[NMAX + 1];
int cost[NMAX + 1][NMAX + 1];
int flux[NMAX + 1][NMAX + 1];
int p[NMAX + 1];

int dist[NMAX + 1];

int newdist[NMAX + 1];
int newcost[NMAX + 1][NMAX + 1];

void bellman( int n, int s ) {
    queue <int> q;
    q.push( s );
    while ( !q.empty() ) {
        int node = q.front();
        q.pop();
        for ( auto it : edges[node] ) {
            if ( flux[node][it] > 0 && dist[it] > dist[node] + cost[node][it] ) {
                dist[it] = dist[node] + cost[node][it];
                q.push( it );
            }
        }
    }
}
int main() {
    ifstream fin( "fmcm.in" );
    ofstream fout( "fmcm.out" );

    int n, m, i, s, d, a, b, c, z, min_cost = 0, max_flux = 0;
    fin >> n >> m >> s >> d;
//    cin >> n >> m >> s >> d;
    for ( i = 0; i < m; i ++ ) {
        fin >> a >> b >> c >> z;
//        cin >> a >> b >> c >> z;
        edges[a].push_back( b );
        edges[b].push_back( a );
        cost[a][b] = z;
        cost[b][a] = -z;

        flux[a][b] = c;
    }
    for ( i = 1; i <= n; i ++ ) {
        random_shuffle( edges[i].begin(), edges[i].end() );
    }
    for ( i = 1; i <= n; i ++ ) {
        dist[i] = INF;
    }
    bellman( n, s );

    for ( i = 1; i <= n; i ++ ) {
        for ( auto it : edges[i] ) {
            newcost[i][it] = dist[i] + cost[i][it] - dist[it];
        }
    }
    int ok = 1;
    do {
        memset( p, 0, sizeof( p ) );
        p[s] = -1;
        newdist[s] = 0;
        priority_queue <pair<int, int>> pq;
        pq.push( { 0, s } );
        while ( !pq.empty() && pq.top().second != d ) {
            pair <int, int> node = pq.top();
            pq.pop();
            node.first = -node.first;
            if ( newdist[node.second] == node.first ) {
                for ( auto it : edges[node.second] ) {
                    if ( flux[node.second][it] > 0 && ( !p[it] || node.first + newcost[node.second][it] < newdist[it] ) ) {
                        p[it] = node.second;
                        newdist[it] = node.first + newcost[node.second][it];
                        pq.push( { -node.first, it } );
                    }
                }
            }
        }
        if ( !pq.empty() ) {
            int f = INF, c = 0;
            for ( int i = d; i != s; i = p[i] ) {
                f = min( f, flux[p[i]][i] );
                c += cost[p[i]][i];
            }
            for ( int i = d; i != s; i = p[i] ) {
                flux[p[i]][i] -= f;
                flux[i][p[i]] += f;
            }
            min_cost += c * f;
            max_flux += f;
        } else {
            ok = 0;
        }
    } while ( ok );
    fout << min_cost;
//    cout << min_cost;
    return 0;
}