Pagini recente » Cod sursa (job #2477406) | Cod sursa (job #2534515) | Cod sursa (job #1308611) | Cod sursa (job #95820) | Cod sursa (job #816248)
Cod sursa(job #816248)
#include <algorithm>
#include <cassert>
#include <cstdio>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
using namespace std;
inline int next_int() {int d;scanf("%d", &d);return d;}
const int INF = 1e9;
int V, E;
int min_cost, max_flow;
int capacity[350][350], cost[350][350], dist[350], prev[350];
bool seen[350];
int Q[350 * 350];
vector<int> G[350];
inline void add_edge(int a, int b, int c, int d) {
capacity[a][b] = c, cost[a][b] = +d, G[a].push_back(b);
capacity[b][a] = 0, cost[b][a] = -d, G[b].push_back(a);
}
inline void run(const int source, const int sink) {
while (true) {
for (int v = 0; v < V; v++) {
prev[v] = -1;
seen[v] = false;
dist[v] = INF;
}
int front = 0, back = 0;
Q[back++] = source;
dist[source] = 0;
seen[source] = true;
while (back - front > 0) {
int u = Q[front++];
for (size_t i = 0; i < G[u].size(); i++) {
int v = G[u][i];
if (dist[u] < INF && capacity[u][v] && dist[u] + cost[u][v] < dist[v]) {
dist[v] = dist[u] + cost[u][v];
prev[v] = u;
if (!seen[v]) {
Q[back++] = v;
seen[v] = true;
}
}
}
seen[u] = false;
}
if (dist[sink] == INF) {
break;
}
int path_flow = INF;
int path_cost = dist[sink];
for (int where = sink; where != source; where = prev[where]) {
path_flow = min(path_flow, capacity[prev[where]][where]);
}
for (int where = sink; where != source; where = prev[where]) {
capacity[prev[where]][where] -= path_flow;
capacity[where][prev[where]] += path_flow;
}
min_cost += path_flow * path_cost;
max_flow += path_flow;
}
}
int main() {
freopen("fmcm.in", "r", stdin);
freopen("fmcm.out", "w", stdout);
V = next_int();
E = next_int();
int source = next_int() - 1;
int sink = next_int() - 1;
for (int e = 0; e < E; e++) {
int a = next_int() - 1;
int b = next_int() - 1;
int c = next_int();
int d = next_int();
add_edge(a, b, c, d);
}
run(source, sink);
printf("%d\n", min_cost);
return 0;
}