Cod sursa(job #2470492)

Utilizator Alex18maiAlex Enache Alex18mai Data 9 octombrie 2019 12:09:41
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.76 kb
//ALEX ENACHE

#include <vector>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <unordered_map>
#include <time.h>
#include <iomanip>
#include <deque>
#include <math.h>
#include <assert.h>
#include <stack>
#include <bitset>
#include <random>

using namespace std;

//#include <iostream>
#include <fstream>
ifstream cin("fmcm.in"); ofstream cout("fmcm.out");

const int inf = 1e9;
const int NMAX = 355;

int n, m, S, D;

vector < int > gr[NMAX];
int cap[NMAX][NMAX];
int cost[NMAX][NMAX];
int DP[NMAX][2];
int used[NMAX];

queue < int > q;

void norm() {
	for (auto& x : DP[0]) {
		x = inf;
	}
	q.push(S);
	DP[S][0] = 0;
	while (!q.empty()) {
		int now = q.front();
		q.pop();
		used[now] = 0;
		for (auto& x : gr[now]) {
			if (cap[now][x] && DP[x][0] > DP[now][0] + cost[now][x]) {
				DP[x][0] = DP[now][0] + cost[now][x];
				if (!used[x]) {
					used[x] = 1;
					q.push(x);
				}
			}
		}
	}
}

int flow[NMAX][NMAX];
int dad[NMAX];
int dp[NMAX];

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

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

int flux() {
	for (auto& x : dp) {
		x = inf;
	}
	dp[S] = 0;
	Q.push({ S , 0 });
	while (!Q.empty()) {
		pair < int, int > now = Q.top();
		Q.pop();
		//cerr<<now.first<<'\n';
		if (now.second != dp[now.first]) {
			continue;
		}
		for (auto& x : gr[now.first]) {
			int new_dp = dp[now.first] + cost[now.first][x] + DP[now.first][0] - DP[x][0];
			if (cap[now.first][x] > flow[now.first][x] && dp[x] > new_dp) {
				dp[x] = new_dp;
				DP[x][1] = DP[now.first][1] + cost[now.first][x];
				dad[x] = now.first;
				Q.push({ x , dp[x] });
			}
		}
	}
	for (int i = 1; i <= n; i++) {
		DP[i][0] = DP[i][1];
	}
	if (dp[D] != inf) {
		return 1;
	}
	return 0;
}

int main() {

	//freopen("input", "r", stdin);freopen("output", "w", stdout);

	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	cout << setprecision(10) << fixed;
	mt19937 rng((long long)(new char));
	srand(time(nullptr));

	cin >> n >> m >> S >> D;

	for (int i = 1; i <= m; i++) {
		int a, b, c, z;
		cin >> a >> b >> c >> z;
		gr[a].push_back(b);
		gr[b].push_back(a);
		cap[a][b] = c;
		cost[a][b] = z;
		cost[b][a] = -z;
	}

	norm();

	int ans = 0;

	while (flux()) {
		//cerr<<"stop"<<'\n';
		int now = D;
		int MIN = inf;
		while (now != S) {
			MIN = min(MIN, cap[dad[now]][now] - flow[dad[now]][now]);
			now = dad[now];
		}
		now = D;
		while (now != S) {
			flow[dad[now]][now] += MIN;
			flow[now][dad[now]] -= MIN;
			ans += MIN * cost[dad[now]][now];
			now = dad[now];
		}
	}

	cout << ans;

	return 0;
}