Cod sursa(job #2901678)

Utilizator BeilandArnoldArnold Beiland BeilandArnold Data 14 mai 2022 11:10:50
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.73 kb
#include <cstdio>

#include <cstring>

#include <vector>

#include <queue>



const int MAXN=350;

const int INF=0x3F3F3F3F;

typedef std::pair<unsigned,int> PUI;

typedef std::pair<unsigned,unsigned> PUU;



std::vector< unsigned > Adj[MAXN+1];

unsigned F[MAXN+1][MAXN+1];

int Cst[MAXN+1][MAXN+1];

int Dist[MAXN+1];

int ndist[MAXN+1];

unsigned tati[MAXN+1];

int real_d[MAXN+1];



static std::priority_queue<PUU,std::vector<PUU>,std::greater<PUU> > pq;



bool enqueued[MAXN+1];



inline void BellmanFord(const unsigned n, const unsigned s){

    std::queue<unsigned> q;

    q.push(s);

    while(!q.empty()){

        unsigned f=q.front(); q.pop(); enqueued[f]=false;

        for(auto it=Adj[f].begin();it!=Adj[f].end();++it)

            if(Dist[*it]>Dist[f]+Cst[f][*it]&&F[f][*it]!=0){

                Dist[*it]=Dist[f]+Cst[f][*it];

                if(!enqueued[*it]) q.push(*it);

            }

    }

}



bool ameliorare_Dijkstra(int &cstmin, const unsigned &n, const unsigned &s, const unsigned &d){

    std::memset(ndist,0x3F,4*(n+1));

    std::memset(real_d,0x3F,4*(n+1));



    pq.push(PUU(0,s));

    ndist[s]=0; real_d[s]=0;



    while(!pq.empty()){

        int cdist=pq.top().first; unsigned cnod=pq.top().second;

        pq.pop();



        if(cdist==ndist[cnod])

            for(auto it=Adj[cnod].begin();it!=Adj[cnod].end();++it){

                int temp;

                if( (F[cnod][*it]>0) && (ndist[*it] > (temp=cdist+Dist[cnod]-Dist[*it]+Cst[cnod][*it])) ){

                    ndist[*it]=temp;

                    pq.push(PUU(temp,*it));

                    tati[*it]=cnod;

                    real_d[*it]=real_d[cnod]+Cst[cnod][*it];

                }

            }

    }



    if(ndist[d]!=INF){ //am gasit drum de ameliorare

        unsigned cflux=INF;

        for(unsigned i=d;i!=s;i=tati[i])

            if(F[tati[i]][i]<cflux)

                cflux=F[tati[i]][i];



        for(unsigned i=d;i!=s;i=tati[i]){

            F[tati[i]][i]-=cflux;

            F[i][tati[i]]+=cflux;

        }



        cstmin+=cflux*real_d[d];



        std::memcpy(Dist,real_d,4*(n+1));

        return true;

    }

    else return false;



}



int main(){

    std::freopen("fmcm.in","rt",stdin);

    std::freopen("fmcm.out","wt",stdout);





    unsigned n,m,s,d;

    std::scanf("%d %d %d %d",&n,&m,&s,&d);



    std::memset(Dist,0x3F,4*(n+1));



    for(unsigned i=0;i<m;++i){

        unsigned x,y,c; int z; std::scanf("%d %d %d %d",&x,&y,&c,&z);

        Adj[x].push_back(y);

        Adj[y].push_back(x);

        F[x][y]=c;

        Cst[x][y]=z;

        Cst[y][x]=-z;

    }



    Dist[s]=0;



    BellmanFord(n,s);



    int cstmin=0;



    while(ameliorare_Dijkstra(cstmin,n,s,d));



    std::printf("%d \n",cstmin);

}