Cod sursa(job #2470491)

Utilizator Alex18maiAlex Enache Alex18mai Data 9 octombrie 2019 12:08:37
Problema Flux maxim de cost minim Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.54 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 fin("input"); ofstream fout("output");
ifstream fin("fmcm.in"); ofstream fout("fmcm.out");

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

int n, m, S, D;

vector < int > gr[MAXN];

int cost[MAXN][MAXN];
int cap[MAXN][MAXN];
int flow[MAXN][MAXN];

int DP[MAXN][2];
int dp[MAXN];
int dad[MAXN];

queue < int > Q;
int used[MAXN];

void norm() {
	for (int i = 1; i <= n; i++) {
		DP[i][0] = inf;
	}
	DP[S][0] = 0;
	Q.push(S);
	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]) {
					Q.push(x);
					used[x] = 1;
				}
			}
		}
	}
}

priority_queue < pair < int, int >, vector < pair < int, int > > > q;

int flux() {
	
	for (int i = 1; i <= n; i++) {
		dp[i] = inf;
		dad[i] = 0;
	}
	dp[S] = 0;
	dad[S] = S;
	q.push({ 0 , S });

	int ok = 0;

	while (!q.empty()) {
		pair < int, int > aux = q.top(); int nod = aux.second, val = aux.first;
		q.pop();

		if (nod == D) {
			ok = 1;
			continue;
		}
		if (val != dp[nod]) {
			continue;
		}

		for (auto& x : gr[nod]) {
			if (cap[nod][x] > flow[nod][x]) {
				int now = val + cost[nod][x] + DP[nod][0] - DP[x][0];
				if (dp[x] > now) {
					dp[x] = now;
					dad[x] = nod;
					DP[x][1] = DP[nod][1] + cost[nod][x];
					q.push({ dp[x] , x });
				}
			}
		}

	}

	for (int i = 1; i <= n; i++) {
		DP[i][0] = DP[i][1];
	}

	return ok;

}

int main() {

	fin >> n >> m >> S >> D;

	norm();

	while (m--) {
		int a, b, c, d;
		fin >> a >> b >> c >> d;
		gr[a].push_back(b);
		gr[b].push_back(a);
		cap[a][b] += c;
		cost[a][b] += d;
		cost[b][a] -= d;
	}

	int ans = 0;

	while (flux()) {
		
		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) {
			ans += MIN * cost[dad[now]][now];
			flow[dad[now]][now] += MIN;
			flow[now][dad[now]] -= MIN;
			now = dad[now];
		}

	}

	fout << ans;


	return 0;
}