Cod sursa(job #2641948)

Utilizator georgerapeanuRapeanu George georgerapeanu Data 13 august 2020 10:38:46
Problema Flux maxim de cost minim Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.81 kb
#include <cstdio>
#include <queue>
#include <algorithm>
#include <vector>

using namespace std;

const int NMAX = 350;

int cap[NMAX + 5][NMAX + 5];
int cst[NMAX + 5][NMAX + 5];
int flux[NMAX + 5][NMAX + 5];

int n,m,S,D;
vector<int> graph[NMAX + 5];

FILE *f = fopen("fmcm.in","r");
FILE *g = fopen("fmcm.out","w");

int d[NMAX + 5];
int reald[NMAX + 5];
int oldd[NMAX + 5];
int father[NMAX + 5];

int q[NMAX + 5];
int stq,drq;
bool inq[NMAX + 5];

void bellman(int S,int D){
    for(int i = 1;i <= n;i++){
        inq[i] = 0;
        d[i] = 1e9;
    }

    d[S] = 0;
    q[stq = drq = 1] = S;

    while(stq <= drq){
        int nod = q[stq++];
        inq[nod] = 0;
        for(auto it:graph[nod]){
            if(flux[nod][it] < cap[nod][it] && d[it] > d[nod] + cst[nod][it]){
                d[it] = d[nod] + cst[nod][it];
                if(inq[it] == 0){
                    q[++drq] = it;
                    inq[it] = 1;
                }
            }
        }
    }

    for(int i = 1;i <= n;i++){
        oldd[i] = d[i];
        d[i] = 0;
    }
}

long long ans;

bool dijkstra(int S,int D){
    for(int i = 1;i <= n;i++){
        d[i] = 1e9;
        reald[i] = 1e9;
    }

    d[S] = 0;
    reald[S] = 0;
    priority_queue<pair<int,int>,vector<pair<int,int> > ,greater<pair<int,int> > > pq;

    pq.push({0,S});

    while(!pq.empty()){
        pair<int,int> tmp = pq.top();pq.pop();
        int dist = tmp.first;
        int nod = tmp.second;
        if(dist != d[nod]){
            continue;
        }
        if(nod == D){
            break;
        }
        for(auto it:graph[nod]){
            if(flux[nod][it] < cap[nod][it] && d[it] > d[nod] + cst[nod][it] - oldd[it] + oldd[nod]){
                father[it] = nod;
                d[it] = d[nod] + cst[nod][it] - oldd[it] + oldd[nod];
                reald[it] = reald[nod] + cst[nod][it];
                pq.push({d[it],it});
            }
        }
    }

    if(d[D] == 1e9){
        return 0;
    }

    int flow_cost = 0;
    int minflow = 1e9;

    for(int nod = D;nod != S;nod = father[nod]){
        minflow = min(minflow,cap[father[nod]][nod] - flux[father[nod]][nod]);
        flow_cost += cst[father[nod]][nod];
    }

    for(int nod = D;nod != S;nod = father[nod]){
        flux[father[nod]][nod] += minflow;
        flux[nod][father[nod]] -= minflow;
    }

    for(int i = 1;i <= n;i++){
        oldd[i] = d[i];
    }
    ans += 1LL * flow_cost * minflow;
    return 1;
}

int main(){

    fscanf(f,"%d %d %d %d",&n,&m,&S,&D);

    for(int i = 1;i <= m;i++){
        int x,y,c,z;
        fscanf(f,"%d %d %d %d",&x,&y,&c,&z);
        graph[x].push_back(y);
        graph[y].push_back(x);
        cap[x][y] = c;
        cst[x][y] = z;
        cst[y][x] = -z;
    }

    bellman(S,D);

    while(dijkstra(S,D));

    fprintf(g,"%lld\n",ans);

    fclose(f);
    fclose(g);

    return 0;
}