Cod sursa(job #1700736)

Utilizator mihai995mihai995 mihai995 Data 11 mai 2016 07:34:58
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.15 kb
#include <fstream>
#include <iostream>
#include <cstring>
#include <vector>
#include <queue>
#include <cassert>
using namespace std;

const int N = 1001, inf = 0x3f3f3f3f;

struct Edge{
	int y, c;
	Edge(int y, int c) : y(y), c(c) {};
	inline bool operator<(const Edge& E) const {
		return c > E.c;
	}
};

vector<Edge> graph[N]; //bidirectional
int cap[N][N], diff[N][N], T[N], dist[N], bf_dist[N], n;
bool use[N];

bool dijkstra(int x, int D){
	memset(dist, inf, sizeof(dist));
	memset(use, false, sizeof(use));
	memset(T, -1, sizeof(T));
	priority_queue<Edge> Q;
	Q.emplace(x, 0);
	dist[x] = 0;

	while ( !Q.empty() ){
		x = Q.top().y;
		int c = Q.top().c;
		Q.pop();

		if ( dist[x] != c )
			continue;

		for ( Edge e : graph[x] ) {
			c = dist[x] + e.c + bf_dist[x] - bf_dist[e.y];
			if ( diff[x][e.y] && c < dist[e.y] ){
				Q.emplace(e.y, c);
				dist[e.y] = c;
				T[e.y] = x;
			}
		}
	}
	for (int i = 1; i <= n; i++)
		if ( bf_dist[i] == inf || dist[i] == inf )
			bf_dist[i] = inf;
		else
			bf_dist[i] += dist[i];
	return dist[D] != inf;
}

char q[5];
void prepare_graph(int* dist, int x){
	memset(dist, inf, N * sizeof(*dist));
	queue<int> Q;
	dist[x] = 0;
	Q.push(x);

	while ( !Q.empty() ){
		x = Q.front();
		Q.pop();

		for (Edge e : graph[x])
			if ( cap[x][e.y] && dist[x] + e.c < dist[e.y] ){
				dist[e.y] = dist[x] + e.c;
				Q.push(e.y);
			}
	}
}

int maxflow(int S, int D){
	prepare_graph(bf_dist, S);
	memcpy( diff, cap, sizeof(cap) );
	int tot = 0;
	while ( dijkstra(S, D) ) {
		int F = inf;
		for (int i = D; i != S; i = T[i])
			F = min( F, diff[ T[i] ][i] );
		for (int i = D; i != S; i = T[i]){
			diff[ T[i] ][i] -= F;
			diff[i][ T[i] ] += F;
		}
		tot += F;
	}
	return tot; //actual flow(x, y) = cap[x][y] - flow[x][y];
}
int get_cost(){
	int cost = 0;
	for (int x = 1; x <= n; x++)
		for (Edge e : graph[x])
			cost += e.c * (cap[x][e.y] - diff[x][e.y]);
	return cost / 2;
}

int main(){
	ifstream in("fmcm.in");
	ofstream out("fmcm.out");
	int S, D, m, x, y, c;

	in >> n >> m >> S >> D;
	while (m--){
		in >> x >> y;
		in >> cap[x][y] >> c;
		graph[x].emplace_back(y, c);
		graph[y].emplace_back(x, -c);
	}
	maxflow(S, D);
	out << get_cost() << '\n';
	return 0;
}