Cod sursa(job #2880304)

Utilizator MateiAruxandeiMateiStefan MateiAruxandei Data 29 martie 2022 16:51:47
Problema Flux maxim de cost minim Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.25 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("fmcm.in");
ofstream fout("fmcm.out");

const int NMAX(355);
using ll = long long;
vector<int> G[NMAX];
int cost[NMAX][NMAX], dist[NMAX];
int flux[NMAX][NMAX], par[NMAX], cap[NMAX][NMAX];
bool inQ[NMAX];

struct MFMC
{
    inline void addEdge(int st, int dr, int flx, int cst){
        G[st].push_back(dr);
        G[dr].push_back(st);
        cap[st][dr] = flx;
        cost[st][dr] = cst;
        cost[dr][st] = -cst;
    }
    inline bool BellManFord(int st, int fs)
    {
        for(int i = 0; i <= fs; ++i)
            inQ[i] = 0, dist[i] = 1e9, par[i] = -1;
        queue<int> q;
        q.push(st);
        inQ[st] = 1;
        dist[st] = 0;
        while(!q.empty())
        {
            int nd = q.front();
            q.pop();
            inQ[nd] = 0;
            for(auto it: G[nd])
                if(flux[nd][it] < cap[nd][it])
                {
                    if(dist[nd] + cost[nd][it] < dist[it])
                    {
                        dist[it] = dist[nd] + cost[nd][it];
                        par[it] = nd;
                        if(!inQ[it]){
                            inQ[it] = 1;
                            q.push(it);
                        }
                    }
                }
        }
        return (par[fs] != -1);
    }
    inline ll Flow(int st, int dr){
        ll rez = 0;
        while(BellManFord(st, dr)){
            int cur = dr;
            int flx = INT_MAX;
            ll sum = 0;
            while(cur != st){
                flx = min(flx, cap[par[cur]][cur] - flux[par[cur]][cur]);
                sum += cost[par[cur]][cur];
                cur = par[cur];
            }

            cur = dr;
            while(cur != st){
                flux[par[cur]][cur] += flx;
                flux[cur][par[cur]] -= flx;
                cur = par[cur];
            }
            rez += flx * sum;
        }
        return rez;
    }
};

int main()
{
    int n, m, s, d;
    fin >> n >> m >> s >> d;

    MFMC Sis;
    for(int i = 1; i <= m; ++i){
        int x, y, c, z;
        fin >> x >> y >> c >> z;
        Sis.addEdge(x, y, c, z);
    }

    fout << Sis.Flow(s, d) << '\n';
    return 0;
}