Cod sursa(job #2613765)

Utilizator andreisontea01Andrei Sontea andreisontea01 Data 10 mai 2020 17:15:16
Problema Flux maxim de cost minim Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.88 kb
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 355;

#define nod first
#define cst second

class cmp{
    public:
    bool operator ()(pair<int, int> &a, pair<int, int> &b){
        return a.cst > b.cst;
    }
};

queue<int> coada;
vector<int> graf[MAXN], rev[MAXN];
priority_queue<pair<int, int>, vector<pair<int, int>>, cmp> pq;
int flux[MAXN][MAXN], cost[MAXN][MAXN], newcost[MAXN][MAXN], sursa[MAXN], dist[MAXN], newdist[MAXN];
bool viz[MAXN];

int n, m, s, d;

void bellmanFord(){
    for(int i = 1; i <= n; ++i) dist[i] = 1e9;
    coada.push(s);
    dist[s] = 0;
    while(!coada.empty()){
        int x = coada.front();
        coada.pop();
        for(auto y: graf[x]){
            if(dist[y] > dist[x] + cost[x][y]){
                dist[y] = dist[x] + cost[x][y];
                coada.push(y);
            }
        }
    }
}

bool dijkstra(){
    memset(viz, 0, n + 1);
    for(int i = 1; i <= n; ++i) newdist[i] = 1e9;
    newdist[s] = 0;
    bool rez = 0;
    pq.push({s, newdist[s]});
    while(!pq.empty()){
        int x = pq.top().nod, xdist = pq.top().cst;
        pq.pop();
        if(newdist[x] != xdist) continue;
        for(auto y: graf[x]){
            if(flux[x][y] > 0 && newdist[y] > xdist + newcost[x][y]){
                newdist[y] = xdist + newcost[x][y];
                sursa[y] = x;
                if(y == d) rez = 1;
                pq.push({y, newdist[y]});
            }
        }
    }
    return rez;
}

int main()
{
    ifstream fin("fmcm.in");
    ofstream fout("fmcm.out");
    fin >> n >> m >> s >> d;
    for(int i = 1; i <= m; ++i){
        int x, y;
        fin >> x >> y;
        fin >> flux[x][y] >> cost[x][y];
        cost[y][x] = -cost[x][y];
        graf[x].push_back(y);
    }
    bellmanFord();
    for(int i = 1; i <= n; ++i){
        for(int j = 1; j <= n; ++j)
            newcost[i][j] = 1e9;
    }
    for(int i = 1; i <= n; ++i)
        for(auto x: graf[i]) rev[x].push_back(i);
    for(int i = 1; i <= n; ++i)
        for(auto j: graf[i])
            newcost[i][j] = cost[i][j] + dist[i] - dist[j];
    int mxflux = 0, mncost = 0;
    bool isflux = 1;
    while(isflux){
        isflux = dijkstra();
        for(auto x: rev[d]){
            if(newdist[x] + newcost[x][d] == newdist[d]){
                int mnflux = 1e9, crt = d;
                while(crt != s){
                    mnflux = min(mnflux, flux[sursa[crt]][crt]);
                    crt = sursa[crt];
                }
                crt = d;
                while(crt != s){
                    flux[sursa[crt]][crt] -= mnflux;
                    flux[crt][sursa[crt]] += mnflux;
                    crt = sursa[crt];
                }
                mxflux += mnflux;
                mncost += mnflux * (dist[x] + cost[x][d]);
            }
        }
    }
    fout << mncost;
    return 0;
}