Cod sursa(job #812678)

Utilizator ahmed.abdraboahmed.abdrabo ahmed.abdrabo Data 14 noiembrie 2012 11:02:49
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.88 kb
#include <algorithm>
#include <cassert>
#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;

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

const int INF = 1 << 30;

struct MinCostMaxFlow {
	int V, E, min_cost, max_flow;
	vector<int> from, to, capacity, cost;
	MinCostMaxFlow(int n) {
		V = n, E = 0, min_cost = 0, max_flow = 0;
		from.clear(), to.clear(), capacity.clear(), cost.clear();
	}
	void add_edge(int a, int b, int c, int d) {
		E++, from.push_back(a), to.push_back(b), capacity.push_back(c), cost.push_back(+d);
		E++, from.push_back(b), to.push_back(a), capacity.push_back(0), cost.push_back(-d);
	}
	void run(const int source, const int sink) {
		while (true) {
			vector<int> dist(V, INF), edge(V, -1);
			dist[source] = 0;
			for (int v = 0; v < V; v++) {
				for (int e = 0; e < E; e++) {
					int a = from[e], b = to[e], c = capacity[e], d = cost[e];
					if (dist[a] < INF && dist[a] + d < dist[b] && c > 0) {
						dist[b] = dist[a] + d;
						edge[b] = e;
					}
				}
			}
			if (dist[sink] == INF) {
				break;
			}
			int now = sink, path_flow = INF, path_cost = 0;
			while (now != source) {
				path_flow = min(path_flow, capacity[edge[now]]);
				now = from[edge[now]];
			}
			now = sink;
			while (now != source) {
				capacity[edge[now] ^ 0] -= path_flow;
				capacity[edge[now] ^ 1] += path_flow;
				path_cost += cost[edge[now]] * path_flow;
				now = from[edge[now]];
			}
			min_cost += path_cost;
			max_flow += path_flow;
		}
	}
};

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