Cod sursa(job #2685737)

Utilizator davidcotigacotiga david davidcotiga Data 17 decembrie 2020 16:50:00
Problema Flux maxim de cost minim Scor 100
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>


using namespace std;

const int inf = (int)2e9 + 7;
const int max_n = (int)4e2 + 5;

int n, m, sink, dest;

vector<int> g[max_n];

int flow[max_n][max_n], capacity[max_n][max_n], cost[max_n][max_n];

bool visited[max_n];

int d[max_n], dad[max_n], old_d[max_n], new_d[max_n];

void bellman_ford() {
	for (int i = 1; i <= n; ++i) {
		old_d[i] = inf;
	}
	queue<int> q;
	visited[sink] = true;
	old_d[sink] = 0;
	q.push(sink);
	while ((int)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 (old_d[v] > old_d[u] + cost[u][v]) {
					old_d[v] = old_d[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, sink));
	visited[sink] = true;
	d[sink] = new_d[sink] = 0;
	while ((int)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] + old_d[u] - old_d[v]) {
					d[v] = d[u] + cost[u][v] + old_d[u] - old_d[v];
					new_d[v] = new_d[u] + cost[u][v];
					dad[v] = u;
					pq.push(make_pair(d[v], v));
				}
			}
		}
	}
	for (int i = 1; i <= n; ++i) {
		old_d[i] = new_d[i];
	}
	return (d[dest] < inf);
}

int main() {
	int u, v, cst, cap, max_flow = 0, min_flow;
	ifstream in("fmcm.in");
	ofstream out("fmcm.out");
	in >> n >> m >> sink >> dest;
	for (int i = 0; i < m; ++i) {
		in >> 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() == true) {
		min_flow = inf;
		for (int i = dest; i != sink; i = dad[i]) {
			min_flow = min(min_flow, capacity[dad[i]][i] - flow[dad[i]][i]);
		}
		for (int i = dest; i != sink; i = dad[i]) {
			flow[dad[i]][i] += min_flow;
			flow[i][dad[i]] -= min_flow;
		}
		max_flow += min_flow * new_d[dest];
	}
	out << max_flow << "\n";
	return 0;
}