Cod sursa(job #2807209)

Utilizator vladth11Vlad Haivas vladth11 Data 23 noiembrie 2021 16:12:33
Problema Flux maxim de cost minim Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.56 kb
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define debug(x) cerr << #x << " " << x << "\n"
#define debugs(x) cerr << #x << " " << x << " "

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair <ll, ll> pii;
typedef pair <long double, pii> muchie;

const ll NMAX = 351;
const ll VMAX = 21;
const ll INF = (1LL << 55);
const ll MOD = 998244353;
const ll BLOCK = 318;
const ll base = 31;
const ll nr_of_bits = 30;

vector <ll> v[NMAX];

struct edge{
    ll from, to, cap, cost;
}edges[25001];

ll cnt = 0, s, d, n, viz[NMAX];
ll dist[NMAX], last[NMAX];

void addEdge(ll a, ll b, ll c, ll cost){
    edges[++cnt] = {a, b, c, cost};
    v[a].push_back(cnt);
    edges[++cnt] = {b, a, 0, -cost};
    v[b].push_back(cnt);
}

ll invers(ll x){
    if(x % 2)
        return (x + 1);
    return (x - 1);
}

bool Dijkstra(){
    for(ll i = 1; i <= n; i++){
        viz[i] = 0, dist[i] = 2e9;
        last[i] = 0;
    }
    priority_queue <pii> pq;
    pq.push({0, s});
    dist[s] = 0;
    while(pq.size()){
        while(pq.size() && viz[pq.top().second])
            pq.pop();
        if(!pq.size())
            continue;
        ll node = pq.top().second;
        pq.pop();
        if(node == d)
            return 1;
        viz[node] = 1;
        for(auto x : v[node]){
            if(!edges[x].cap)
                continue;
            ll to = edges[x].to;
            ll cost = edges[x].cost;
            if(dist[node] + cost < dist[to]){
                dist[to] = dist[node] + cost;
                pq.push({-dist[to], to});
                last[to] = x;
            }
        }
    }
    return 0;
}

ll flow(){
    ll sol = 0;
    while(Dijkstra()){
        ll minim = 2e9;
        ll node = last[d];
        while(node != 0){
            minim = min(minim, edges[node].cap);
            node = last[edges[node].from];
        }
        sol += minim * dist[d];
        node = last[d];
        while(node != 0){
            edges[node].cap -= minim;
            edges[invers(node)].cap += minim;
            node = last[edges[node].from];
        }
    }
    return sol;
}

int main() {
    ifstream cin("fmcm.in");
    ofstream cout("fmcm.out");
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    ll m, i;
    cin >> n >> m >> s >> d;
    for(i = 1; i <= m; i++){
        ll a, b, c, d;
        cin >> a >> b >> c >> d;
        addEdge(a, b, c, d);
    }
    cout << flow();
    return 0;
}