Cod sursa(job #3203841)

Utilizator OvidRata Ovidiu Ovid Data 14 februarie 2024 19:53:02
Problema Flux maxim de cost minim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.43 kb
#include<bits/stdc++.h>
using namespace std;
/*
string numeFisier="fmcm";
ifstream fin(numeFisier+".in"); ofstream fout(numeFisier+".out");
#define cin fin
#define cout fout
*/
#define INIT  ios_base :: sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define mp make_pair
#define pb push_back
#define ft first
#define sc second
#define ll long long
#define pii pair<int, int>
#define count_bits __builtin_popcount
//#define int ll


/*
Infoarena MinimumCostFlow

    O(min(N * M^2 * logN, F * M * logN ) )



    MAXN may need to be changed
*/



#define MAXN 355
class MinCostFlow{

public:




int N, M, S, D;
int C[MAXN][MAXN], Cst[MAXN][MAXN];
int InitialC[MAXN][MAXN];
vector<int> con[MAXN];
int F, FCst;

int old_d[MAXN]; char inQ[MAXN];
queue<int> Q;

int d[MAXN], real_d[MAXN], p[MAXN];
priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > H;

vector<pair<int,vector<int>>>Paths;

inline bool dijkstra()
{
    memset(d, 0x3f, sizeof(d));
    d[S] = 0; real_d[S] = 0;
    H.push(make_pair(d[S], S));

    for (; !H.empty(); )
    {
        int cst = H.top().first, nod = H.top().second;
        H.pop();
        if (d[nod] != cst)
            continue;

        vector<int> :: iterator it;
        for (it = con[nod].begin(); it != con[nod].end(); it++)
            if (C[nod][*it])
            {
                int new_d = d[nod] + Cst[nod][*it] + old_d[nod] - old_d[*it];
                if (new_d < d[*it])
                {
                    d[*it] = new_d;
                    real_d[*it] = real_d[nod] + Cst[nod][*it];
                    p[*it] = nod;
                    H.push(make_pair(d[*it], *it));
                }
            }
    }
    memcpy(old_d, real_d, sizeof(d));
    if (d[D] == 0x3f3f3f3f)
        return false;

    int Min = 0x3f3f3f3f, curCst = 0;
    for (int aux = D; aux != S; aux = p[aux])
        Min = min(Min, C[p[aux]][aux]),
        curCst += Cst[p[aux]][aux];

    F += Min;
    FCst += Min * real_d[D];
    vector<int> path;
    for (int aux = D; aux != S; aux = p[aux])
        C[p[aux]][aux] -= Min,
        C[aux][p[aux]] += Min,
        path.push_back(aux);
        ;
    path.push_back(S);

    Paths.push_back(mp(Min, path));

    return true;
}

inline bool bellmanFord()
{
    memset(old_d, 0x3f, sizeof(old_d));
    old_d[S] = 0;

    for (Q.push(S), inQ[S] = 1; !Q.empty(); Q.pop())
    {
        vector<int> :: iterator it;
        int i = Q.front();
        inQ[i] = 0;

        for (it = con[i].begin(); it != con[i].end(); it++)
            if (C[i][*it])
            {
                if (old_d[i] + Cst[i][*it] >= old_d[*it])
                    continue;

                old_d[*it] = old_d[i] + Cst[i][*it];
                if (inQ[*it])
                    continue;

                inQ[*it] = 1;
                Q.push(*it);
            }
    }

    if (old_d[D] == 0x3f3f3f3f)
        return false;

    return true;
}





void DoFlow( int n, int m, int s/*source*/, int d/*destination,sink */, vector< vector<int> > &Edges ){
    N=n, M=m, S=s, D=d;

    for(auto vec:Edges){

        int x=vec[0], y=vec[1];

        C[x][y]=InitialC[x][y]=vec[2];
        Cst[x][y]=vec[3];

        con[x].push_back(y);
        con[y].push_back(x);

        Cst[y][x] = -Cst[x][y];

    }


    F = FCst = 0;
    bellmanFord();
    for (; dijkstra(); );
    //{cout<<"dijk\n";}


}

void Clean(){

    for(int i=1; i<=N; i++){
        for(int j=1; j<=N; j++){
            Cst[i][j]=0;
            C[i][j]=0;
            InitialC[i][j]=0;
        }
        con[i].clear();
        old_d[i]=0;
        inQ[i]=0;
        d[i]=0;
        real_d[i]=0;
        p[i]=0;
    }
    F=0;
    FCst=0;
    while(!Q.empty()){
        Q.pop();
    }
    while(!H.empty()){
        H.pop();
    }
    Paths.clear();


}

} Solver=MinCostFlow() ;



int32_t main(){
    INIT



    int n, m ,s, d;
    vector<vector<int>> Edges;
    cin>>n>>m>>s>>d;
    for(int i=1; i<=m; i++){
        int x, y, c, cst;
        cin>>x>>y>>c>>cst;
        Edges.pb({x, y, c, cst});
    }

    Solver.DoFlow(n, m, s, d, Edges);
    //cout<<Solver.F<<"\n";
    //cout<<Solver.FCst;

    Solver.Clean();

    Solver.DoFlow(n, m, s, d, Edges);
    cout<<Solver.FCst;

    return 0;
}