Cod sursa(job #2685403)

Utilizator davidcotigacotiga david davidcotiga Data 16 decembrie 2020 20:24:01
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.39 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <set>
#include <algorithm>
#include <stack>
#include <vector>
#include <iomanip>
#include <cstdio>

#define INF (int)2e9 + 7
#define MAXN (int)4e2 + 5

using namespace std;

ifstream fin("fmcm.in");
ofstream fout("fmcm.out");

int N, M, source, dest;

vector<int> G[MAXN];

int flow[MAXN][MAXN];
int capacity[MAXN][MAXN];
int cost[MAXN][MAXN];

bool visited[MAXN];

int D[MAXN];
int dad[MAXN];
int oldD[MAXN];
int newD[MAXN];

void bellman_ford() {
	for (int i = 1; i <= N; ++i)
		oldD[i] = INF;

	queue<int> Q;

	visited[source] = true;
	oldD[source] = 0;

	Q.push(source);

	while (Q.size() > 0) {
		int u = Q.front();
		Q.pop();
		visited[u] = true;
		for (int v : G[u]) {
			if (flow[u][v] < capacity[u][v]) {
				if (oldD[v] > oldD[u] + cost[u][v]) {
					oldD[v] = oldD[u] + cost[u][v];
					if (visited[v] == false) {
						visited[v] = true;
						Q.push(v);
					}
				}
			}
		}
	}
}

bool Dijkstra() {
	for (int i = 1; i <= N; ++i) {
		D[i] = INF;
	}

	priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> PQ;

	PQ.push(make_pair(0, source));

	visited[source] = true;
	D[source] = newD[source] = 0;

	while (PQ.size() > 0) {
		int u = PQ.top().second;
		int c = PQ.top().first;

		PQ.pop();

		if (D[u] != c)
			continue;

		for (int v : G[u]) {
			if (flow[u][v] < capacity[u][v]) {
				if (D[v] > D[u] + cost[u][v] + oldD[u] - oldD[v]) {
					D[v] = D[u] + cost[u][v] + oldD[u] - oldD[v];
					newD[v] = newD[u] + cost[u][v];
					dad[v] = u;
					PQ.push(make_pair(D[v], v));
				}
			}
		}
	}

	for (int i = 1; i <= N; ++i) {
		oldD[i] = newD[i];
	}
	return (D[dest] < INF);
}

int main() {
	int u, v, cst, cap, maxFlow = 0, minFlow;

	fin >> N >> M >> source >> dest;

	for (int i = 0; i < M; ++i) {
		fin >> u >> v >> cap >> cst;
		capacity[u][v] = cap;
		cost[u][v] = cst;
		cost[v][u] = -cst;
		G[u].push_back(v);
		G[v].push_back(u);
	}

	bellman_ford();

	while (Dijkstra()) {
		minFlow = INF;

		for (int i = dest; i != source; i = dad[i])
			minFlow = min(minFlow, capacity[dad[i]][i] - flow[dad[i]][i]);

		for (int i = dest; i != source; i = dad[i]) {
			flow[dad[i]][i] += minFlow;
			flow[i][dad[i]] -= minFlow;
		}
		maxFlow += minFlow * newD[dest];
	}

	fout << maxFlow << "\n";

	return 0;
}