Cod sursa(job #2600770)

Utilizator alex2209alexPavel Alexandru alex2209alex Data 13 aprilie 2020 11:14:04
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.66 kb
#include <bits/stdc++.h>

using namespace std;
class InParser {
private:
	FILE *fin;
	char *buff;
	int sp;

	char read_ch() {
		++sp;
		if (sp == 4096) {
			sp = 0;
			fread(buff, 1, 4096, fin);
		}
		return buff[sp];
	}

public:
	InParser(const char* nume) {
		fin = fopen(nume, "r");
		buff = new char[4096]();
		sp = 4095;
	}

	InParser& operator >> (int &n) {
		char c;
		while (!isdigit(c = read_ch()) && c != '-');
		int sgn = 1;
		if (c == '-') {
			n = 0;
			sgn = -1;
		} else {
			n = c - '0';
		}
		while (isdigit(c = read_ch())) {
			n = 10 * n + c - '0';
		}
		n *= sgn;
		return *this;
	}
};
InParser f("fmcm.in");
ofstream g("fmcm.out");
const int NMAX = 350;
const int INF = 1e9;
int N, M, S, D;
vector <int > muchii[NMAX + 2];
int cap[NMAX + 2][NMAX + 2], cost[NMAX + 2][NMAX + 2], flow[NMAX + 2][NMAX + 2];
int bef[NMAX + 2];
int oldD[NMAX + 2], realD[NMAX + 2], d[NMAX + 2];
bool inQ[NMAX + 2];
priority_queue <pair <int, int>, vector <pair <int, int>>, greater <pair <int, int>> > pq;
bool Dijkstra()
{
    for(int i = 1; i <= N; i++)
        d[i] = INF;
    pq.push({0, S});
    d[S] = realD[S] = 0;
    while(!pq.empty())
    {
        pair <int, int> current = pq.top();
        pq.pop();
        int node = current.second;
        int cst = current.first;
        if(d[node] != cst)
            continue;
        for(auto it : muchii[node])
            if(flow[node][it] < cap[node][it])
            {
                int distToIt = d[node] + cost[node][it] + oldD[node] - oldD[it];
                if(distToIt < d[it])
                {
                    d[it] = distToIt;
                    realD[it] = realD[node] + cost[node][it];
                    bef[it] = node;
                    pq.push({d[it], it});
                }
            }
    }
    for(int i = 1; i <= N; i++)
        oldD[i] = realD[i];
    return (d[D] != INF);
}
int main()
{
    f >> N >> M >> S >> D;
    for(int i = 1; i <= M; i++)
    {
        int x, y, c, z;
        f >> x >> y >> c >> z;
        muchii[x].push_back(y);
        muchii[y].push_back(x);
        cap[x][y] = c;
        cost[x][y] = z;
        cost[y][x] = -z;
    }
    int minCost = 0;
    while(Dijkstra())
    {
        int pumpFlo = INF;
        for(int node = D; node != S; node = bef[node])
            pumpFlo = min(pumpFlo, cap[bef[node]][node] - flow[bef[node]][node]);
        for(int node = D; node != S; node = bef[node])
        {
            flow[bef[node]][node] += pumpFlo;
            flow[node][bef[node]] -= pumpFlo;
        }
        minCost += pumpFlo * realD[D];
    }
    g << minCost << '\n';
    return 0;
}