Cod sursa(job #2476479)

Utilizator gabib97Gabriel Boroghina gabib97 Data 18 octombrie 2019 22:16:35
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.8 kb
#include <bits/stdc++.h>

#define N 352
using namespace std;
using pp = pair<int, int>;

int n, m, src, dest, cap[N][N], parent[N], dn[N], dv[N], d[N];
vector<pp> G[N];

void bellmanFord()
{
	queue<int> Q;
	bool *o = new bool[n + 1];
	fill(dv + 1, dv + n + 1, INT_MAX);
	Q.push(src);
	o[src] = true;
	dv[src] = 0;

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

		for (pp &py : G[x]) {
			int y = py.first;
			if (cap[x][y] > 0 && dv[y] > dv[x] + py.second) {
				dv[y] = dv[x] + py.second;
				if (!o[y])
					Q.push(y), o[y] = true;
			}
		}
	}
}

priority_queue<pp, vector<pp>, greater<pp>> Q;

bool dijkstra()
{
	int x, y;
	fill(d + 1, d + n + 1, INT_MAX);
	d[src] = 0;
	Q.push(make_pair(0, src));
	while (!Q.empty()) {
		pp p = Q.top();
		Q.pop();
		if (d[p.second] != p.first) continue;

		x = p.second;
		int dx = d[x] + dv[x];
		for (const pp &py : G[x])
			if (cap[x][py.first] > 0) {
				int dist = dx + py.second - dv[py.first]; // adjust distances to become positive
				if (d[py.first] > dist) {
					y = py.first;
					d[y] = dist;
					parent[y] = x;
					dn[y] = dn[x] + py.second;
					Q.push(make_pair(dist, y));
				}
			}
	}
	memcpy(dv, dn, sizeof(dn));
	return d[dest] != INT_MAX;
}

int main()
{
	freopen("fmcm.in", "r", stdin);
	freopen("fmcm.out", "w", stdout);
	scanf("%i%i%i%i", &n, &m, &src, &dest);

	int x, y, c, w;
	while (m--) {
		scanf("%i%i%i%i", &x, &y, &c, &w);
		G[x].emplace_back(y, w);
		G[y].emplace_back(x, -w);
		cap[x][y] = c;
	}

	// compute min costs
	bellmanFord();

	// find max flow
	int cost = 0;
	while (dijkstra()) {
		w = INT_MAX;
		for (int i = dest; i != src; i = parent[i])
			w = min(w, cap[parent[i]][i]);
		for (int i = dest; i != src; i = parent[i])
			cap[parent[i]][i] -= w, cap[i][parent[i]] += w;

		cost += w * dn[dest];
	}
	printf("%i", cost);
	return 0;
}