Cod sursa(job #2850943)

Utilizator Vlad_AnicaAnica-Popa Vlad-Ioan Vlad_Anica Data 17 februarie 2022 20:17:02
Problema Flux maxim de cost minim Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.19 kb
#include <stdio.h>
#include <iostream>
#include <vector>

using namespace std;
const int NMAX = 350, INF = 1e9, QSIZE = (1 << 9) - 1;

int flow[NMAX + 1][NMAX + 1], cap[NMAX + 1][NMAX + 1], cst[NMAX + 1][NMAX + 1];
int father[NMAX + 1], minDist[NMAX + 1], q[1 << 9];
bool inQ[NMAX + 1];
vector<int> adj[NMAX + 1];

int bellmanFord(int src, int sink);
int pushFlow(int sink);

int main() {
    int n, m, src, sink, i, nd1, nd2, minCst;
    FILE *fin = fopen("fmcm.in", "r");

    fscanf(fin, "%d%d%d%d", &n, &m, &src, &sink);
    for (i = 0; i < m; i++) {
        fscanf(fin, "%d%d", &nd1, &nd2);
        fscanf(fin, "%d%d", &cap[nd1][nd2], &cst[nd1][nd2]);
        cst[nd2][nd1] = -cst[nd1][nd2];

        adj[nd1].push_back(nd2);
        adj[nd2].push_back(nd1);
    }

    fclose(fin);

    minCst = 0;
    while (bellmanFord(src, sink))
        minCst += pushFlow(sink);

    FILE *fout = fopen("fmcm.out", "w");
    fprintf(fout, "%d", minCst);
    fclose(fout);

    return 0;
}

int bellmanFord(int src, int sink) {

    for (int i = 1; i <= NMAX; i++)
        minDist[i] = INF, father[i] = 0;
    int l = 0, r = 1;
    q[0] = src;
    inQ[src] = 1;
    minDist[src] = 0;

    while (l != r) {
        int nd = q[l];
        l = (l + 1) & QSIZE;
        inQ[nd] = 0;

        for (auto nxt: adj[nd]) {
            if (flow[nd][nxt] != cap[nd][nxt] && minDist[nxt] > minDist[nd] + cst[nd][nxt]) {
                minDist[nxt] = minDist[nd] + cst[nd][nxt];
                father[nxt] = nd;
                if (!inQ[nxt]) {
                    inQ[nxt] = 1;
                    q[r] = nxt;
                    r = (r + 1) & QSIZE;
                }
            }
        }
    }
    return father[sink];
}
int pushFlow(int sink) {
    int nd = sink, minFlow = INF, minCst;

    while (father[nd]) {
        minFlow = min(minFlow, cap[father[nd]][nd] - flow[father[nd]][nd]);
        nd = father[nd];
    }

    nd = sink;
    minCst = 0;
    while (father[nd]) {
        minCst += cst[father[nd]][nd] * minFlow;
        flow[father[nd]][nd] += minFlow;
        flow[nd][father[nd]] -= minFlow;

        nd = father[nd];
    }
    return minCst;
}