Cod sursa(job #3361765)

Utilizator iuli_morariuIuli Morariu iuli_morariu Data 28 iulie 2026 13:21:59
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.28 kb
#include <algorithm>
#include <iostream>
#include <fstream>
#include <climits>
#include <vector>
#include <stack>
#include <cmath>
#include <queue>
// #include <bits/std++.h>
#define in  fin
#define out fout

using namespace std;
const int NMAX = 355;

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

// maybe
// we'll meet at abar
// we'll drive
// a funky
// hueeeeee

struct muchie{
    int x, y, pereche, c, f, cost;
};

vector<int> g[NMAX];
vector<muchie> mch;
int dist[NMAX];
int dist_new[NMAX];
int the_real_ones[NMAX]; // those who know...
int sursie, noelle;
pair<int, int> last[NMAX];
int n;

int sans = 0, papyrus = 0; // flux si cost

void add_muchie(int x, int y, int c, int cost){
    int id = mch.size(), idp = mch.size() + 1;
    mch.push_back({x, y, idp, c, 0,  cost});
    mch.push_back({y, x, id,  0, 0, -cost});

    g[x].push_back(id);
    g[y].push_back(idp);
}

void clopot_barbat(){
    for(int i = 1; i <= n; i++) dist[i] = INT_MAX;
    dist[sursie] = 0;
    for(int i = 0; i < n; i++){
        for(const muchie &a : mch){
            if( dist[a.x] != INT_MAX && dist[a.y] > dist[a.x] + a.c ){
                dist[a.y] = dist[a.x] + a.c;
            }
        }
    }
}

bool dijikstra(){
    priority_queue< pair<int, int>, vector< pair<int, int> >, greater<pair<int, int> > > pq;

    for(int i = 1; i <= n; i++){
        last[i] = {0, -1};
        dist_new[i] = INT_MAX;
    }

    dist_new[sursie] = 0;

    // cerr << "dijikstra\n";

    pq.push({0, sursie});
    while(!pq.empty()){
        int x = pq.top().second, d = pq.top().first;
        pq.pop();

        if(d != dist_new[x]) continue;
        // cerr << "x = " << x << " dist = " << dist[x] << '\n';

        for(const int &id : g[x]){
            int y = mch[id].y;
            int cost = mch[id].cost;
            // cerr << "--> incerc cu y = " << y << '\n';
            // cerr << "--> f = " << mch[id].f << " din " << mch[id].c << '\n';
            // fnaf songs so peak
            if(mch[id].c > mch[id].f){
                int new_dist = dist_new[x] + cost + dist[x] - dist[y];
                // cerr << "--> new_dist = " << new_dist << " dist_new = " << dist_new[y] << '\n';
                // cerr << "--> dist = " << dist[x] << " dist[y] = " << dist[y] << '\n';
                if(new_dist < dist_new[y]){
                    dist_new[y] = new_dist;
                    last[y] = {x, id};
                    the_real_ones[y] = the_real_ones[x] + cost;
                    // cerr << "--> yuppie\n";
                    pq.push( {dist_new[y], y} );
                }
            }
        }
    }
    
    for(int i = 1; i <= n; i++){
        dist[i] = the_real_ones[i];
    }

    // w d gaster from deltarune
    // built it all from an empty room
    // mike the cat yes that is gaster
    // and the titan also gaster
    // in the bunker sits that gaster
    // entry 17's ol master
    // kris is gaster
    // susie gaster
    // noelle gaster
    // the knight is an amalgamate
    // built by gaster intricate
    // gaster is actually green
    // da da da da da du da da

    // cerr << "noelle = " << dist_new[noelle] << '\n';

    if(dist_new[noelle] == INT_MAX){
        return 0; // imposibil gng getout
        // nupid stigger
    }

    // o sa imi relaxez muchiile aici

    int minim_ude = INT_MAX, asriel = 0;

    // cerr << "fac drumu inapoi\n";

    int nod = noelle;
    while(nod != sursie){
        // cerr << "--> nod = " << nod << '\n';
        int id = last[nod].second;
        minim_ude = min(minim_ude, mch[id].c - mch[id].f);
        asriel += mch[id].cost;
        nod = last[nod].first;
    }

    // cerr << "minim_ude = " << minim_ude << '\n';
    // cerr << "asriel = " << asriel << '\n';

    sans += minim_ude;
    papyrus += minim_ude * asriel;

    nod = noelle;
    while(last[nod].second != -1){
        int id = last[nod].second;
        mch[id].f += minim_ude;
        mch[ mch[id].pereche ].f -= minim_ude;

        nod = last[nod].first;
    }
    return 1;
}

signed main(){
    ios_base::sync_with_stdio(false);
    in.tie(NULL);

    int m;
    in >> n >> m >> sursie >> noelle;

    for(int i = 0; i < m; i++){
        int x, y, c, cost; in >> x >> y >> c >> cost;
        add_muchie(x, y, c, cost);
    }

    clopot_barbat();

    while(dijikstra()){
        // yay
    }

    out << papyrus << '\n';

    return 0;
}