Cod sursa(job #3038603)

Utilizator SerbanCaroleSerban Carole SerbanCarole Data 27 martie 2023 16:07:54
Problema Flux maxim de cost minim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.8 kb
#include <fstream>
#include <queue>
using namespace std;

ifstream cin("flux.in");
ofstream cout("flux.out");

const int MAX = 351;

const int inf = 1e9 + 1;

int n , x , dist[MAX] , m , y , c , source ,
sink , z , cap[MAX][MAX] , f[MAX][MAX], total_flow , pre[MAX] , cost[MAX][MAX];

bool in_q[MAX];

struct muchie{

    int y , c;
};

struct cmp{

    bool operator()( int a , int b){

        return dist[a] > dist[b];
    }

};

vector <muchie> g[MAX];

void bf(){

    queue<int>q;

    for(int i = 1 ; i <= n ; i++){

        dist[i] = inf;
    }

    dist[source] = 0;

    q.push(source);

    while(!q.empty()){

        x = q.front(); q.pop();

        in_q[x] = 0;

        for(auto it : g[x]){

            if( cap[x][it.y] - f[x][it.y] > 0 && dist[it.y] > dist[x] + it.c ){

                dist[it.y] = dist[x] + it.c;
                if(!in_q[it.y]){

                    q.push(it.y);
                    in_q[it.y] = 1;
                }
            }
        }

    }

    for(int i = 1 ; i <= n ; i++){

        x = i;

        int sz = g[x].size();

        for(int j = 0 ; j < sz ; j++){

            g[x][j].c = g[x][j].c + dist[x] - dist[g[x][j].y];
        }
    }
}

int dijkstra(){

    for(int i = 1 ; i <= n ; i++){

        dist[i] = inf;
        pre[i] = 0;
    }

    dist[source] = 0;

    priority_queue<int,vector<int>,cmp>pq;

    pq.push(source);

    while(!pq.empty()){

        x = pq.top();

        pq.pop();

        if(x == sink){

            return dist[x];
        }

        for(auto it : g[x]){

            if(cap[x][it.y] - f[x][it.y] > 0 && dist[it.y] > dist[x] + it.c){

                dist[it.y] = dist[x] + it.c;

                pre[it.y] = x;

                pq.push(it.y);
            }
        }
    }

    return inf;

}

int main()
{
    cin >> n >> m >> source >> sink;

    while(m--){

        cin >> x >> y >> c >> z;

        g[x].push_back({y,z});
        g[y].push_back({x,-z});

        cap[x][y] = c;

        cost[x][y] = z;
        cost[y][x] = -z;
    }

    bf();

    int total_cost = 0;

    while(1){

        int x = dijkstra();

        if(x == inf) break;

        int new_flow = 1e9 + 1;

        int aux = sink;

        x = 0;

        while(pre[sink]){

            new_flow = min(new_flow,cap[pre[sink]][sink] - f[pre[sink]][sink]);

            x += cost[pre[sink]][sink];

            sink = pre[sink];
        }

        sink = aux;

        while(pre[sink]){

            f[pre[sink]][sink] += new_flow;
            f[sink][pre[sink]] -= new_flow;

            sink = pre[sink];
        }

        sink = aux;

        total_cost += x*new_flow;
    }

    cout << total_cost;

    return 0;
}