Cod sursa(job #1754885)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 8 septembrie 2016 21:55:25
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.22 kb
#include <bits/stdc++.h>
using namespace std;

constexpr int maxn = 400;

using ll = long long;

constexpr int inf = 0x3f3f3f3f;

int n, m, s, t, len[maxn][maxn] = {},
	dist[maxn] = {}, real_dist[maxn] = {}, father[maxn] = {}, old_dist[maxn] = {}, flux_left[maxn][maxn] = {};

bitset<maxn> done = 0;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
ll rez = 0;
vector<int> vec[maxn];

bool bellman_ford(){
	memset(old_dist, 0x3f, sizeof(old_dist));
	old_dist[s] = 0;

	queue<int> q;
	bitset<maxn> in_q = 0;

	q.push(s), in_q[s] = true;
	while(!q.empty()){
		const int cur = q.front();
		q.pop(), in_q[cur] = false;
		for(const auto next : vec[cur]){
			if(flux_left[cur][next] && old_dist[cur] + len[cur][next] < old_dist[next]){
				old_dist[next] = old_dist[cur] + len[cur][next];
				if(!in_q[next]){
					in_q[next] = true;
					q.push(next); } } } }

	return dist[t] != inf; }

bool dijkstra_and_flux_step(){
	pq.emplace(0, s);
	memset(dist, 0x3f, sizeof(dist));
	dist[s] = 0, real_dist[s] = 0;

	while(!pq.empty()){
		const int cur = pq.top().second, d_cur = pq.top().first;
		pq.pop();
		if(dist[cur] != d_cur || cur == t){
			continue; }
		for(const auto next : vec[cur]){
			if(flux_left[cur][next] &&
			   !done[next] &&
			   dist[cur] + len[cur][next] + old_dist[cur] - old_dist[next] < dist[next]){
				dist[next] = dist[cur] + len[cur][next] + old_dist[cur] - old_dist[next];
				real_dist[next] = real_dist[cur] + len[cur][next];
				father[next] = cur;
				pq.emplace(dist[next], next); } } }
	memcpy(old_dist, dist, sizeof(dist));
	if(dist[t] == inf){
		return false; }

	ll d_flux = inf;
	for(int nod = t; nod != s; nod = father[nod]){
		d_flux = min<ll>(d_flux, flux_left[father[nod]][nod]); }

	rez += real_dist[t] * d_flux;
	for(int nod = t; nod != s; nod = father[nod]){
		flux_left[father[nod]][nod] -= d_flux;
		flux_left[nod][father[nod]] += d_flux; }

	return true; }

int main(){
	ifstream f("fmcm.in");
	ofstream g("fmcm.out");

	f >> n >> m >> s >> t;
	for(int i = 0, x, y, c, l; i < m; ++i){
		f >> x >> y >> c >> l;
		vec[x].push_back(y);
		vec[y].push_back(x);

		flux_left[x][y] = c;
		len[x][y] = l, len[y][x] = -l; }

	bellman_ford();
	while(dijkstra_and_flux_step());

	g << rez << endl;

	return 0; }