Cod sursa(job #3180663)

Utilizator SorinBossuMarian Sorin SorinBossu Data 5 decembrie 2023 18:46:00
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.15 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
std::ifstream in("fmcm.in");
std::ofstream out("fmcm.out");

int n, m, s, t;
const long long inf = 1e17;
constexpr unsigned int nmax = 351;

struct edge
{
    int u,  v;
    long long ca, f = 0, c;

    edge(int u, int v, long long ca, long long c): u(u), v(v), ca(ca), c(c) {}
};

int cnt = 0;
std::vector<edge> e;
std::vector<int> adj[nmax];

void add(int u, int v, long long ca, long long c)
{
    e.emplace_back(u, v, ca, c);
    e.emplace_back(v, u, 0, -c);
    adj[u].emplace_back(cnt);
    adj[v].emplace_back(cnt+1);
    cnt += 2;
}

int p[nmax], pe[nmax];
long long c[nmax], nff[nmax];
bool inq[nmax];

bool bf()
{
    for ( int i = 1; i <= n; ++i )
       c[i] = inf, inq[i] = false, p[i] = -1, nff[i] = inf;
    p[s] = 0;
    c[s] = 0;
    inq[s] = true;
    std::queue<int> q;
    q.emplace(s);

    while ( !q.empty() )
    {
        int u = q.front();
        inq[u] = false;
        q.pop();
        for ( auto id : adj[u] )
        {
            int v = e[id].v;

            if ( e[id].ca - e[id].f < 1 )
              continue;
            if ( c[v] <= c[u] + e[id].c )
            {
               continue;
            }
            c[v] = c[u] + e[id].c;
            nff[v] = std::min(nff[u], e[id].ca - e[id].f);
            p[v] = u;
            pe[v] = id;
            if ( inq[v] )
               continue;
            inq[v] = true;
            q.emplace(v);
        }
    }

    return p[t] != -1;
}

long long fmcm()
{
    long long r = 0;

    while ( bf() ){
        int u = t;
        while ( u != s )
        {
            int ee = pe[u];
            e[ee].f += nff[t];
            e[ee ^ 1].f -=nff[t];
            u = p[u];
        }
        r += nff[t] * c[t];
    }
    return r;
}


int  main()
{
    std::ios_base::sync_with_stdio(false);
    in.tie(0);
    in >> n >> m >> s >> t;
    
    for ( int i = 1; i <= m; ++i ){
        int a, b, ca, c;
        in >> a >> b >> ca >> c;
        add(a, b, ca, c);
    }
    out << fmcm();
       
    return 0;
}