Cod sursa(job #2278088)

Utilizator UncleGrandpa925Hoang Long Vuong UncleGrandpa925 Data 7 noiembrie 2018 11:39:16
Problema Flux maxim de cost minim Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.77 kb
/*input
5 7 2 5
3 1 7 -1
1 4 3 0
3 4 3 -4
1 5 7 0
4 5 1 1
2 5 8 -3
2 3 4 -3
*/
#include <bits/stdc++.h>
using namespace std;
#define sp ' '
#define endl '\n'
#define fi first
#define se second
#define mp make_pair
#define __builtin_popcount __builtin_popcountll
#define int long long
#define bit(x,y) ((x>>y)&1LL)
#define loop(i,l,r) for(int i=(int)l; i<=(int)r; i++)
#define rloop(i,l,r) for(int i=(int)l; i>=(int)r; i--)

template <class T1, class T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &a) {
	return os << '(' << a.first << ", " << a.second << ')';
}
template <class T>
ostream &operator<<(ostream &os, const vector<T> &a) {
	os << '[';
	for (int i = 0; i < a.size(); i++)
		os << a[i] << (i < a.size() - 1 ? ", " : "");
	os << ']';
	return os;
}

const int N = 355;
const int INF = 1e18;
class MinCostMaxFlow {
private:
	struct data {
		int u, v, cap, f, cost;
		data (int _u = 0, int _v = 0, int _cap = 0, int _f = 0, int _cost = 0): u(_u), v(_v), cap(_cap), f(_f), cost(_cost) {};
		int other(data x, int z) {
			if (x.u == z) return x.v;
			return x.u;
		}
	} E;
	vector<data> e;
	vector<vector<int> > a;
	int dis[N], par[N];
	int S, T;
	bool dijkstra() {
		priority_queue<pair<int, int> , vector<pair<int, int> >, greater<pair<int, int> > > pq;
		memset(dis, 127, sizeof(dis)); dis[S] = 0; pq.push(mp(0, S));
		memset(par, 0, sizeof(par));
		while (!pq.empty()) {
			int u = pq.top().se; int _ = pq.top().fi; pq.pop();
			if (_ != dis[u]) continue;
			for (auto id : a[u]) {
				data &t = e[id];
				int v = E.other(t, u);
				if (t.f < t.cap && dis[v] > dis[u] + t.cost) {
					dis[v] = dis[u] + t.cost;
					par[v] = id;
					pq.push(mp(dis[v], v));
				}
			}
		}
		return par[T] != 0;
	}
	void dfs() {
		int delta = INF;
		int u = T;
		while (1) {
			delta = min(delta, e[par[u]].cap - e[par[u]].f);
			u = E.other(e[par[u]], u);
			if (u == S) break;
		}
		u = T;
		while (1) {
			e[par[u]].f += delta;
			e[par[u] ^ 1].f -= delta;
			u = E.other(e[par[u]], u);
			if (u == S) break;
		}
	}
public:
	void init(int _S, int _T) {
		S = _S; T = _T;
		a.assign(N, vector<int>());
	}
	void addEdge(int u, int v, int cap, int cost) {
		e.push_back(data(u, v, cap, 0, cost));
		e.push_back(data(v, u, 0, 0, -cost));
		a[u].push_back(e.size() - 2);
		a[v].push_back(e.size() - 1);
	}
	int solve() {
		int ret = 0;
		while (dijkstra()) {
			dfs();
		}
		for (int i = 0; i < e.size(); i++) if (e[i].f > 0) ret += e[i].f * e[i].cost;
		return ret;
	}
} MCMF;


signed main() {
#ifndef UncleGrandpa
	ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#endif
	freopen("fmcm.in", "r", stdin);
	freopen("fmcm.out", "w", stdout);
	int n, m, S, T;
	cin >> n >> m >> S >> T;
	MCMF.init(S, T);
	while (m--) {
		int u, v, x, y;
		cin >> u >> v >> x >> y;
		MCMF.addEdge(u, v, x, y);
	}
	cout << MCMF.solve() << endl;
}