Cod sursa(job #1700727)

Utilizator mihai995mihai995 mihai995 Data 11 mai 2016 05:38:09
Problema Flux maxim de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2.16 kb
#include <fstream>
#include <iostream>
#include <cstring>
#include <vector>
#include <queue>
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;
		Q.pop();

		if ( x == D )
			return true;
		if ( use[x] )
			continue;
		use[x] = true;

		for ( Edge e : graph[x] )
			if ( diff[x][e.y] && dist[x] + e.c < dist[e.y] ){
				dist[e.y] = dist[x] + e.c;
				T[e.y] = x;
				Q.emplace(e.y, dist[e.y]);
			}
	}
	return false;
}

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

//	cerr << "Here?\n";

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

//		cerr << x << ' ' << dist[x] << '\n';

		for (Edge e : graph[x])
			if ( cap[x][e.y] && dist[e.y] < dist[x] + e.c ){
				dist[e.y] = dist[x] + e.c;
				Q.push(e.y);
			}
	}
	for (int x = 1; x <= n; x++)
		for (Edge& e : graph[x])
			e.c += dist[x] - dist[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 += (cap[x][e.y] - diff[x][e.y]) * (e.c + bf_dist[e.y] - bf_dist[x]);
	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;
}