Pagini recente » Cod sursa (job #518599) | Cod sursa (job #85504) | Cod sursa (job #2961706) | Cod sursa (job #2495060) | Cod sursa (job #813561)
Cod sursa(job #813561)
#include <algorithm>
#include <cassert>
#include <cstdio>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
using namespace std;
inline int next_int() {
int n = 0, sign = 1;
char c = getchar_unlocked();
while (!('0' <= c && c <= '9')) {
sign *= c == '-' ? -1 : 1;
c = getchar_unlocked();
}
while ('0' <= c && c <= '9') {
n = n * 10 + c - '0';
c = getchar_unlocked();
}
return sign * n;
}
const int INF = 1e9;
const int MAX_V = 350;
const int MAX_E = 12500 + 12500;
int V, E, min_cost, max_flow, path_cost, path_flow, where;
int from[MAX_E], to[MAX_E], capacity[MAX_E], cost[MAX_E];
int e_begin[MAX_V], e_next[MAX_E];
int dist[MAX_V], prev[MAX_V];
bool seen[MAX_V];
inline void add_edge(const int & a, const int & b, const int & c, const int & d) {
from[E] = a;
to[E] = b;
capacity[E] = c;
cost[E] = +d;
E++;
from[E] = b;
to[E] = a;
capacity[E] = 0;
cost[E] = -d;
E++;
}
inline void run(const int & source, const int & sink) {
for (int v = 0; v < V; v++) {
dist[v] = INF;
e_begin[v] = -1;
}
dist[source] = 0;
for (int e = 0; e < E; e++) {
e_next[e] = e_begin[from[e]];
e_begin[from[e]] = e;
}
for (int v = 0; v < V; v++) {
for (int e = 0; e < E; e++) {
if (dist[from[e]] < INF && capacity[e] > 0 && dist[from[e]] + cost[e] < dist[to[e]]) {
dist[to[e]] = dist[from[e]] + cost[e];
}
}
}
path_cost = dist[sink];
while (true) {
for (int e = 0; e < E; e++) {
cost[e] += dist[from[e]] - dist[to[e]];
}
for (int v = 0; v < V; v++) {
prev[v] = -1;
seen[v] = false;
dist[v] = INF;
}
dist[source] = 0;
priority_queue<pair<int, int> , vector<pair<int, int> > , greater<pair<int, int> > > Q;
Q.push(make_pair(0, source));
while (!Q.empty()) {
int current_dist = Q.top().first;
int current_where = Q.top().second;
Q.pop();
if (!seen[current_where]) {
seen[current_where] = true;
for (int e = e_begin[current_where]; e != -1; e = e_next[e]) {
if (capacity[e] > 0 && current_dist + cost[e] < dist[to[e]]) {
Q.push(make_pair(current_dist + cost[e], to[e]));
dist[to[e]] = current_dist + cost[e];
prev[to[e]] = e;
}
}
}
}
if (dist[sink] == INF) {
break;
}
for (where = sink, path_flow = INF; where != source; where = from[prev[where]]) {
path_flow = min(path_flow, capacity[prev[where]]);
}
for (where = sink; where != source; where = from[prev[where]]) {
capacity[prev[where]] -= path_flow;
capacity[prev[where] ^ 1] += path_flow;
}
path_cost += dist[sink];
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();
int m = next_int();
int s = next_int() - 1;
int d = next_int() - 1;
for (int i = 0; i < m; i++) {
int x = next_int() - 1;
int y = next_int() - 1;
int c = next_int();
int z = next_int();
add_edge(x, y, c, z);
}
run(s, d);
printf("%d\n", min_cost);
return 0;
}