Cod sursa(job #3040962)

Utilizator Tudor06MusatTudor Tudor06 Data 30 martie 2023 18:10:05
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.74 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];
bool viz[NMAX + 1];
int fakedist[NMAX + 1];
int realdist[NMAX + 1];

bool inQueue[NMAX + 1];

int n, s, d;

bool bellman() {
    for ( int i = 1; i <= n; i ++ ) dist[i] = INF;
    dist[s] = 0;
    queue <int> q;
    q.push( s );
    inQueue[s] = true;

    while ( !q.empty() ) {
        int node = q.front();
        q.pop();
        inQueue[node] = false;
        for ( auto vec : edges[node] ) {
            if ( flux[node][vec] > 0 && dist[node] + cost[node][vec] < dist[vec] ) {
                dist[vec] = dist[node] + cost[node][vec];
                if ( !inQueue[vec] ) {
                    q.push( vec );
                    inQueue[vec] = true;
                }
            }
        }
    }

    return ( dist[d] != INF );
}

bool flow() {
    for ( int i = 1; i <= n; i ++ ) {
        viz[i] = false;
        fakedist[i] = INF;
        realdist[i] = dist[i];
        p[i] = 0;
    }
    priority_queue <pair<int, int>> pq;
    pq.push( { 0, s } );
    dist[s] = fakedist[s] = 0;
    while ( !pq.empty() ) {
        int node = pq.top().second;
        pq.pop();
        if ( viz[node] ) continue;
        viz[node] = true;
        for ( auto vec : edges[node] ) {
            if ( flux[node][vec] > 0 && fakedist[node] + realdist[node] + cost[node][vec] - realdist[vec] < fakedist[vec] ) {
                p[vec] = node;
                fakedist[vec] = fakedist[node] + realdist[node] + cost[node][vec] - realdist[vec];
                dist[vec] = dist[node] + cost[node][vec];
                pq.push( { -fakedist[vec], vec } );
            }
        }
    }
    return ( fakedist[d] != INF );
}
int main() {
    ifstream fin( "fmcm.in" );
    ofstream fout( "fmcm.out" );

    int m, i, a, b, min_cost = 0;
    fin >> n >> m >> s >> d;
    for ( i = 0; i < m; i ++ ) {
        fin >> a >> b;
        fin >> flux[a][b] >> cost[a][b];
        edges[a].push_back( b );
        edges[b].push_back( a );
        cost[b][a] = -cost[a][b];
    }
    for ( i = 1; i <= n; i ++ ) {
        random_shuffle( edges[i].begin(), edges[i].end() );
    }
    bellman();
    while ( flow() ) {
        int max_flow = INF, c = 0;
        for ( int i = d; i != s; i = p[i] ) {
            max_flow = min( max_flow, flux[p[i]][i] );
            c += cost[p[i]][i];
        }
        for ( int i = d; i != s; i = p[i] ) {
            flux[p[i]][i] -= max_flow;
            flux[i][p[i]] += max_flow;
        }
        min_cost += c * max_flow;
    }
    fout << min_cost;
    return 0;
}