Cod sursa(job #2876330)

Utilizator George_CristianGeorge Dan-Cristian George_Cristian Data 23 martie 2022 10:50:05
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.75 kb
#include <fstream>
#include <cstring>
#include <vector>
#include <queue>

using namespace std;

ifstream f("fmcm.in");
ofstream g("fmcm.out");

#define NMAX 360
#define INF 0x3f3f3f3f

int n,m,s,d,t[NMAX],viz[NMAX];
int cost[NMAX][NMAX],cap[NMAX][NMAX],flow[NMAX][NMAX];
int Dmin[NMAX],Ddij[NMAX],Ddij_neg[NMAX];
vector<int> G[NMAX];

struct muc{
    int nod, d;

    bool operator<(const muc &other) const{
        if(d != other.d)
            return d > other.d;
        return nod > other.nod;

    }
};

void citire(){
    f>>n>>m>>s>>d;
    int x,y,c,z;
    for(int i=0;i<m;i++){
        f>>x>>y>>c>>z;
        cap[x][y] = c;
        cap[y][x] = 0;

        cost[x][y] = z;
        cost[y][x] = -z;

        G[x].push_back(y);
        G[y].push_back(x);
    }
}

void bellman_ford(){
    queue<int> q;
    memset(Dmin, INF, sizeof(Dmin));
    q.push(s);
    Dmin[s] = 0;
    viz[s] = true;

    while(!q.empty()){
        int x = q.front();
        q.pop();
        viz[x] = false;

        for(auto &nod:G[x])
            if(cap[x][nod] - flow[x][nod] != 0 && Dmin[x] + cost[x][nod] < Dmin[nod]){
                Dmin[nod] = Dmin[x]+cost[x][nod];
                if(!viz[nod]){
                    q.push(nod);
                    viz[nod] = true;
                }
            }
    }
}

bool dijkstra(){
    priority_queue<muc> q;
    memset(viz,0,sizeof(viz));
    memset(Ddij,INF,sizeof(Ddij));
    memset(Ddij_neg,INF,sizeof(Ddij_neg));

    q.push({s,0});
    Ddij[s] = 0;
    Ddij_neg[s] = 0;

    while(!q.empty()){
        int x = q.top().nod;
        q.pop();
        if(viz[x])
            continue;
        viz[x] = true;

        for(auto &nod:G[x])
            if(cap[x][nod]-flow[x][nod]>0){
                int cost_nou = cost[x][nod]+Dmin[x]-Dmin[nod];
                if(Ddij[x] + cost_nou < Ddij[nod]){
                    t[nod] = x;
                    Ddij[nod] = Ddij[x] + cost_nou;
                    Ddij_neg[nod] = Ddij_neg[x] + cost[x][nod];
                    q.push({nod,Ddij[nod]});
                }
            }
    }

    memcpy(Dmin,Ddij_neg,sizeof(Ddij_neg));
    return Ddij[d]!=INF;
}

void rezolvare(){
    int rez = 0;
    bellman_ford();///costuri negative
    while(dijkstra()){ ///cresc consturile negative ca sa nu folosesc tot bellman (ineficient)
        int flowmax = INF;
        for(int nod = d;nod!=s;nod=t[nod])
            flowmax = min(flowmax,cap[t[nod]][nod] - flow[t[nod]][nod]);

        for(int nod = d;nod!=s;nod=t[nod]){
            flow[t[nod]][nod] += flowmax;
            flow[nod][t[nod]] -= flowmax;
        }
        rez += Dmin[d]*flowmax;
    }
    g<<rez;
}

int main()
{
    citire();
    rezolvare();
    return 0;
}