Pagini recente » Cod sursa (job #998048) | Cod sursa (job #1433089) | Cod sursa (job #493709) | Cod sursa (job #630749) | Cod sursa (job #812643)
Cod sursa(job #812643)
#include <algorithm>
#include <cassert>
#include <cstdio>
#include <cstring>
using namespace std;
inline int next_int() {
int d;
scanf("%d", &d);
return d;
}
const int INF = 1e9;
const int V = 350;
const int E = 12500;
int n, m, s, d;
int where, cost = -INF, flow, min_cost, max_flow, dist[V], prev[V];
int e_count;
struct edge_t {
int u, v, capacity, cost;
edge_t(int u = 0, int v = 0, int capacity = 0, int cost = 0) :
u(u), v(v), capacity(capacity), cost(cost) {
}
} edges[E + E];
void mcmf() {
while (true) {
for (int i = 0; i < V; i++) {
dist[i] = INF;
prev[i] = -1;
}
dist[s] = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < e_count; j++) {
edge_t e = edges[j];
if (e.capacity > 0 && dist[e.u] < INF && dist[e.u] + e.cost < dist[e.v]) {
dist[e.v] = dist[e.u] + e.cost;
prev[e.v] = j;
}
}
}
assert(dist[d] > cost);
if (dist[d] == INF) {
return;
}
flow = INF, cost = 0, where = d;
while (prev[where] != -1) {
int e = prev[where];
flow = min(flow, edges[e].capacity);
where = edges[e].u;
}
if (where != s) {
return;
}
assert(where == s);
assert(flow > 0);
where = d;
while (prev[where] != -1) {
int e = prev[where];
edges[e ^ 0].capacity -= flow;
edges[e ^ 1].capacity += flow;
cost += edges[e].cost;
where = edges[e].u;
}
assert(where == s);
assert(cost == dist[d]);
min_cost += flow * cost;
max_flow += flow;
}
}
int main() {
freopen("fmcm.in", "r", stdin);
freopen("fmcm.out", "w", stdout);
n = next_int();
m = next_int();
s = next_int();
d = next_int();
for (int i = 0; i < m; i++) {
int x = next_int();
int y = next_int();
int c = next_int();
int z = next_int();
edges[e_count++] = edge_t(x, y, c, +z);
edges[e_count++] = edge_t(y, x, 0, -z);
}
mcmf();
printf("%d\n", min_cost);
return 0;
}