Cod sursa(job #2715062)

Utilizator adiaioanaAdia R. adiaioana Data 2 martie 2021 21:32:01
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.73 kb
#include <fstream>
#include <vector>
#include <cstring>
#include <queue>
#include <cstdio>
using namespace std;
ifstream cin("fmcm.in");
ofstream cout("fmcm.out");
long long inf=1000000000000;
int N,M,S,D,Cst[400][400], ant[400],fl[400][400], viz[400];
long long Fm,Fcst,old_d[400], d[400], real_d[400];
priority_queue <pair<long long,int>, vector <pair<long long, int> >, greater <pair<long long, int> > > pq;
vector <int> G[400];
queue <int> Q;
inline void scan();
inline void fordfiesta();
inline bool daicstra();

int main()
{
    scan();
    fordfiesta();

    while(daicstra());

    cout<<Fcst<<'\n';
    return 0;
}


inline void scan()
{
    int x,y,z,c;
    cin>>N>>M>>S>>D;
    while(M--)
    {
        cin>>x>>y;
        G[x].push_back(y);
        G[y].push_back(x);
        cin>>z>>c;
        fl[x][y]=z;
        Cst[x][y]=c;
        Cst[y][x]=-c;
    }
}

inline bool daicstra()
{
    int nod;
    long long cost, Min,totcost=0, new_d;
    for(int i=0; i<=N+1; ++i) d[i]=inf;
    d[S]=0; real_d[S]=0;
    pq.push({0,S});
    while(!pq.empty())
    {
        nod=pq.top().second;
        cost=pq.top().first;
        pq.pop();
        if(cost!=d[nod])
            continue;
        for(auto nn:G[nod])
            if(fl[nod][nn])
            {
                new_d=d[nod]+old_d[nod]-old_d[nn]+Cst[nod][nn];
                if(new_d<d[nn])
                {
                    d[nn]=new_d;
                    real_d[nn]=real_d[nod]+Cst[nod][nn];
                    ant[nn]=nod;
                    pq.push({d[nn],nn});
                }
            }
    }
    if(d[D]==inf)
        return 0;
    for(int i=0; i<=N+1; ++i) old_d[i]=real_d[i];
    Min=inf;
    totcost=0;
    for(int nod=D; nod!=S; nod=ant[nod]){
        Min=min(Min, 1ll*fl[ant[nod]][nod]);
        totcost+=Cst[ant[nod]][nod];
    }
    Fcst+=(Min*totcost);
    Fm+=Min;
    for(int nod=D; nod!=S; nod=ant[nod])
    {
        fl[ant[nod]][nod]-=Min;
        fl[nod][ant[nod]]+=Min;
    }

    return 1;
}

inline void fordfiesta()
{
    long long new_d=0;
    int nod=0;
    for(int i=0; i<=N+1; ++i) old_d[i]=inf;
    old_d[S]=0; viz[S]=1;
    Q.push(S);
    while(!Q.empty())
    {
        nod=Q.front();
        Q.pop();
        viz[nod]=0;
        if(nod==D)
            continue;
        for(auto it:G[nod])
            if(fl[nod][it])
            {
                new_d=old_d[nod]+Cst[nod][it];
                if(new_d<old_d[it])
                {
                    old_d[it]=new_d;//ironic
                    if(!viz[it])
                    {
                        viz[it]=1;
                        Q.push(it);
                    }
                }
            }
    }
}