Pagini recente » Cod sursa (job #355367) | Cod sursa (job #2899667) | Cod sursa (job #356440) | Cod sursa (job #276652) | Cod sursa (job #3160184)
#pragma GCC optimize("Ofast,unroll-loops")
#include <algorithm>
#include <iostream>
#include <fstream>
#include <queue>
#define sz(a) ((int)(a).size())
#define all(a) (a).begin(), (a).end()
#define fi first
#define se second
#define lsb(x) (x & (-x))
using namespace std;
inline bool ckmin(int &a, int b) { return a < b ? false : (a = b, true); }
inline bool ckmax(int &a, int b) { return a > b ? false : (a = b, true); }
#ifdef LOCAL
ifstream fin("input.txt");
#define fout cout
#else
#define FILE_NAME "fmcm"
ifstream fin(FILE_NAME ".in");
ofstream fout(FILE_NAME ".out");
#define endl '\n'
#endif
typedef long long ll;
typedef pair<int, int> pii;
const int NMAX = 355;
const int INF = 2e9+5;
struct Edge {
int dest, cap, cost, other;
};
int n, m, source, sink;
vector<Edge> g[NMAX];
int dist[NMAX], pi[NMAX];
int vis[NMAX];
bool inq[NMAX];
pii nxt[NMAX];
void add_edge(int x, int y, int cap, int cost) {
g[x].push_back({ y, cap, cost, sz(g[y]) });
g[y].push_back({ x, 0, -cost, sz(g[x]) - 1 });
}
void read() {
fin >> n >> m >> source >> sink;
for (int i = 1, x, y, c, w; i <= m; i++) {
fin >> x >> y >> c >> w;
add_edge(x, y, c, w);
}
}
void bellman() {
queue<int> qe;
for (int i = 1; i <= n; i++)
pi[i] = INF;
qe.push(source);
pi[source] = 0;
while (!qe.empty()) {
int u = qe.front();
qe.pop();
inq[u] = false;
for (auto &it : g[u]) {
int last = pi[it.dest];
if (it.cap && ckmin(pi[it.dest], pi[u] + it.cost)) {
if (last == pi[it.dest]) exit(-1);
if (!inq[it.dest]) {
qe.push(it.dest);
inq[it.dest] = true;
}
}
}
}
}
void dijkstra() {
for (int i = 1; i <= n; i++) {
dist[i] = INF;
vis[i] = false;
}
priority_queue<pii> pq;
pq.push({0, source});
dist[source] = 0;
nxt[source] = {0, 0};
while (!pq.empty()) {
int d = pq.top().fi;
int u = pq.top().se;
pq.pop();
if (vis[u]) continue;
vis[u] = true;
int i = -1;
for (auto &it : g[u]) {
i++;
if (!it.cap) continue;
if (!vis[it.dest] && ckmin(dist[it.dest], dist[u] + it.cost + pi[u] - pi[it.dest])) {
pi[it.dest] = pi[u] + it.cost;
nxt[it.dest] = { u, i };
pq.push({-dist[it.dest], it.dest});
}
}
}
}
int fmcm() {
int min_cost = 0;
bellman();
while (dijkstra(), dist[sink] != INF) {
int flow = INF, cost = 0;
for (int u = sink; u != source; u = nxt[u].fi) {
Edge &e = g[nxt[u].fi][nxt[u].se];
cost += e.cost;
ckmin(flow, e.cap);
}
for (int u = sink; u != source; u = nxt[u].fi) {
Edge &e = g[nxt[u].fi][nxt[u].se];
e.cap -= flow;
g[u][e.other].cap += flow;
}
min_cost += flow * cost;
}
return min_cost;
}
signed main() {
read();
fout << fmcm() << endl;
return 0;
}