Cod sursa(job #3039173)

Utilizator SerbanCaroleSerban Carole SerbanCarole Data 28 martie 2023 11:34:02
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.84 kb
#include <fstream>
#include <vector>
#include <queue>
using namespace std;

#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("Ofast")

class InParser {
    vector<char> str;
    int ptr;
    ifstream fin;

    char getChar() {
        if (ptr == int(str.size())) {
            fin.read(str.data(), str.size());
            ptr = 0;
        }
        return str[ptr++];
    }

    template<class T>
    T getInt() {
        char chr = getChar();
        while (!isdigit(chr) && chr != '-')
            chr = getChar();
        int sgn = +1;
        if (chr == '-') {
            sgn = -1;
            chr = getChar();
        }
        T num = 0;
        while (isdigit(chr)) {
            num = num * 10 + chr - '0';
            chr = getChar();
        }
        return sgn * num;
    }

public:
    InParser(const char* name) : str(1e5), ptr(str.size()), fin(name) { }
    ~InParser() { fin.close(); }

    template<class T>
    friend InParser& operator>>(InParser& in, T& num) {
        num = in.getInt<T>();
        return in;
    }
};

ofstream cout("fmcm.out");

const int MAX = 351;

const int inf = 1e9 + 1;

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

bool in_q[MAX];

struct muchie{

    int y , c;
};

vector <muchie> g[MAX];

bool bf(){

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

        pre[i] = 0;

        dist[i] = inf;
    }

    dist[source] = 0;

    queue <int> q;

    q.push(source);

    while(!q.empty()){

        x = q.front();

        in_q[x] = 0;

        q.pop();

        for(auto it : g[x]){

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

                pre[it.y] = x;

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

                if(!in_q[it.y]){

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

    if(dist[sink] == inf) return 0;
    return 1;
}

int main(){

    InParser cin("fmcm.in");

    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;
    }

    int sum_cost = 0, new_flow , aux , new_val;

    while(bf()){

        new_val = dist[sink];

        new_flow = inf;

        aux = sink;

        while(pre[sink]){

            new_flow = min(new_flow,cap[pre[sink]][sink] - f[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;

        sum_cost += new_flow*new_val;
    }

    cout << sum_cost;

    return 0;
}