Cod sursa(job #2413587)

Utilizator LucaSeriSeritan Luca LucaSeri Data 23 aprilie 2019 15:51:32
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.86 kb
#include <bits/stdc++.h>
 
using namespace std;

#define all(x) (x).begin(), (x).end()

const int MAXN = 355;
int dist[MAXN], real_d[MAXN], old[MAXN];
int t[MAXN];
vector< int > gr[MAXN];
int cap[MAXN][MAXN];
int cost[MAXN][MAXN];

inline void add(int a, int b, int c, int d) {
	gr[a].emplace_back(b);
	gr[b].emplace_back(a);
	cap[a][b] = c;
	cost[a][b] = d;
	cost[b][a] = -d;
}

class cmp {
public:
	const bool operator () (const pair< int, int > &a, const pair< int, int > &b) const {
		return a.second > b.second;
	}
};

bool dijkstra(int source, int target) {
	memset(t, -1, sizeof t);
	memset(dist, 0x3f, sizeof dist);
	memset(real_d, 0, sizeof real_d);

	priority_queue< pair< int, int >, vector< pair< int, int > >, cmp > h;

	h.push({source, 0});
	dist[source] = 0;
	while(h.size()) {
		int node, c;
		tie(node, c) = h.top();
		h.pop();
		if(c != dist[node]) continue;
		for(auto &x : gr[node]) {
			int newcost = c + cost[node][x] + old[node] - old[x];
			if(newcost < dist[x] && cap[node][x] > 0) {
				dist[x] = newcost;
				real_d[x] = real_d[node] + cost[node][x];
				t[x] = node;
				h.push({x, dist[x]});
			}
		}
	}

	memcpy(old, dist, sizeof old);

	return t[target] != -1;
}


int main() {
	#ifdef BLAT
		freopen("input", "r", stdin);
	#else
		freopen("fmcm.in", "r", stdin);
		freopen("fmcm.out", "w", stdout);
	#endif
 
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	srand(time(nullptr));

	int n, m;
	cin >> n >> m;
	int s, d;
	cin >> s >> d;
	for(int i = 0, a, b, c, d; i < m; ++i) {
		cin >> a >> b >> c >> d;
		add(a, b, c, d);
	}

	int ans = 0;
	while(dijkstra(s, d)) {
		int node = d;
		int flow = 1e9;
		while(node != s) {
			flow = min(flow, cap[t[node]][node]);
			node = t[node];
		}

		node = d;
		while(node != s) {
			cap[t[node]][node] -= flow;
			cap[node][t[node]] += flow;
			node = t[node];
		}

		ans += flow*real_d[d];
	}

	cout << ans << '\n';
	return 0;
}