Cod sursa(job #812647)

Utilizator ahmed.abdraboahmed.abdrabo ahmed.abdrabo Data 14 noiembrie 2012 09:45:20
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.78 kb
#include <algorithm>
#include <cassert>
#include <cstdio>
#include <cstring>

using namespace std;

inline int next_int() {
	int d;
	scanf("%d", &d);
	return d;
}

const int INF = 1e9;
const int V = 350;
const int E = 12500;

int n, m, s, d;
int where, cost = -INF, flow, min_cost, max_flow, dist[V], prev[V];
int e_count;

struct edge_t {
	int u, v, capacity, cost;
	edge_t(int u = 0, int v = 0, int capacity = 0, int cost = 0) :
		u(u), v(v), capacity(capacity), cost(cost) {
	}
} edges[E + E];

void mcmf() {
	while (true) {
		for (int i = 0; i < V; i++) {
			dist[i] = INF;
			prev[i] = -1;
		}
		dist[s] = 0;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < e_count; j++) {
				edge_t e = edges[j];
				if (e.capacity > 0 && dist[e.u] < INF && dist[e.u] + e.cost < dist[e.v]) {
					dist[e.v] = dist[e.u] + e.cost;
					prev[e.v] = j;
				}
			}
		}
		if (dist[d] == INF) {
			return;
		}
		flow = INF, cost = 0, where = d;
		while (prev[where] != -1) {
			int e = prev[where];
			flow = min(flow, edges[e].capacity);
			where = edges[e].u;
		}
		if (where != s) {
			return;
		}
		assert(where == s);
		assert(flow > 0);
		where = d;
		while (prev[where] != -1) {
			int e = prev[where];
			edges[e ^ 0].capacity -= flow;
			edges[e ^ 1].capacity += flow;
			cost += edges[e].cost;
			where = edges[e].u;
		}
		assert(where == s);
		assert(cost == dist[d]);
		min_cost += flow * cost;
		max_flow += flow;
	}
}

int main() {
	freopen("fmcm.in", "r", stdin);
	freopen("fmcm.out", "w", stdout);
	n = next_int();
	m = next_int();
	s = next_int();
	d = next_int();
	for (int i = 0; i < m; i++) {
		int x = next_int();
		int y = next_int();
		int c = next_int();
		int z = next_int();
		edges[e_count++] = edge_t(x, y, c, +z);
		edges[e_count++] = edge_t(y, x, 0, -z);
	}
	mcmf();
	printf("%d\n", min_cost);
	return 0;
}