Cod sursa(job #2602186)

Utilizator Anakin1001George Giorgiu Gica Anakin1001 Data 16 aprilie 2020 09:52:10
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.02 kb
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

ifstream f ( "fmcm.in" );
ofstream g ( "fmcm.out" );

const int N = 351;
const int inf = 125000000;
vector < int > graph[N];
queue < int > q;
int C[N][N], F[N][N], tata[N], cost[N][N];
int d[N], old_d[N], aux[N];
int S, D, n;
bool viz[N];
struct cmp{
    bool operator() ( pair < int, int > &lhs, pair < int, int > &rhs ) const{
        return lhs.second > rhs.second;
    }
};
priority_queue < pair < int , int >, vector < pair < int, int > >, cmp > heap;

void bfs ( int start ){
    for ( int i = 1; i <= n; i++ )
        old_d[i] = inf;
    old_d[start] = 0;
    viz[start] = 1;
    q.push ( start );
    while ( !q.empty ( ) ){
        int node = q.front ( );
        q.pop ( );
        viz[node] = 0;
        for ( int i = 0; i < graph[node].size ( ); i++ ){
            int new_node = graph[node][i];
            if ( old_d[new_node] > old_d[node] + cost[node][new_node] && C[node][new_node] != 0 ){
                old_d[new_node] = old_d[node] + cost[node][new_node];
                if ( viz[new_node] == 0 ){
                    q.push ( new_node );
                    viz[new_node] = 1;
                }
            }
        }
    }
}

bool dijkstra ( int start ){
    for ( int i = 1; i <= n; i++ ){
        viz[i] = tata[i] = 0;
        d[i] = aux[i] = inf;
    }
    d[start] = aux[start] = 0;
    heap.push ( { start, 0 } );
    while( !heap.empty ( ) ){
        int node = heap.top ( ).first;
        int dis = heap.top ( ).second;
        if ( viz[node] == 1 || dis != d[node] ){
            heap.pop ( );
            continue;
        }
        for ( int i = 0; i < graph[node].size ( ); i++ ){
            int new_node = graph[node][i];
            int dist = d[node] + cost[node][new_node] + old_d[node] - old_d[new_node];
            if ( d[new_node] > dist && F[node][new_node] < C[node][new_node] ){
                tata[new_node] = node;
                aux[new_node] = aux[node] + cost[node][new_node];
                d[new_node] = dist;
                heap.push ( { new_node, dist } );
            }
        }
        viz[node] = 1;
    }
    for ( int i = 1; i <= n; i++ )
        old_d[i] = aux[i];
    return d[D] != inf;
}

int main()
{   int m, x, y, c, z, sol = 0, i;
    f >> n >> m >> S >> D;
    for ( i = 1; i <= m; i++ ){
        f >> x >> y >> c >> z;
        C[x][y] = c;
        cost[x][y] = z;
        cost[y][x] = -z;
        graph[x].push_back ( y );
        graph[y].push_back ( x );
    }
    bfs ( S );
    while ( dijkstra ( S ) == 1 ){
        int node = D;
        int Min = inf;
        while ( node != S ){
            Min = min ( Min, C[tata[node]][node] - F[tata[node]][node] );
            node = tata[node];
        }
        node = D;
        while ( node != S ){
            F[tata[node]][node] += Min;
            F[node][tata[node]] -= Min;
            node = tata[node];
        }
        sol += aux[D] * Min;
    }
    g << sol;
    return 0;
}