Pagini recente » Cod sursa (job #1230543) | Cod sursa (job #1937564) | Istoria paginii runda/simulare23.10 | Cod sursa (job #544067) | Cod sursa (job #2247644)
#include <bits/stdc++.h>
using namespace std;
#define NMAX 355
#define kInf (1 << 30)
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
#define cin fin
#define cout fout
int n, m, S, D, p[NMAX], d[NMAX];
int cost[NMAX][NMAX], cap[NMAX][NMAX], flow[NMAX][NMAX], real_d[NMAX], h[NMAX];
vector<int> G[NMAX];
void read_input() {
cin >> n >> m >> S >> D;
for (int i = 1; i <= m; ++i) {
int x, y, c, z;
cin >> x >> y >> c >> z;
cap[x][y] = c;
cost[x][y] = z;
cost[y][x] = -z;
G[x].push_back(y);
G[y].push_back(x);
}
}
void Bellman(int S, int h[NMAX]) {
for (int i = 1; i <= n; ++i) {
h[i] = kInf;
}
queue<int> q;
bitset<NMAX> inQ;
q.push(S);
h[S] = 0;
inQ[S] = 1;
while (!q.empty()) {
auto node = q.front();
q.pop();
inQ[node] = 0;
for (auto it : G[node]) {
if (h[node] + cost[node][it] < h[node] && flow[node][it] < cap[node][it]) {
h[it] = h[node] + cost[node][it];
if (!inQ[it]) {
inQ[it] = 1;
q.push(it);
}
}
}
}
}
int Dijkstra(int S, int D) {
for (int i = 1; i <= n; ++i) {
d[i] = kInf;
real_d[i] = kInf;
p[i] = kInf;
}
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
pq.push({0, S});
d[S] = 0;
real_d[S] = 0;
p[S] = 0;
while (!pq.empty()) {
auto tmp = pq.top();
pq.pop();
auto dist = tmp.first;
auto node = tmp.second;
if (d[node] < dist) {
continue;
}
for (auto it : G[node]) {
long long d_aux = 1LL * d[node] + cost[node][it] + h[node] - h[it];
if (d_aux < 1LL * d[it] && flow[node][it] < cap[node][it]) {
d[it] = d_aux;
real_d[it] = real_d[node] + cost[node][it];
p[it] = node;
pq.push({d[it], it});
}
}
}
for (int i = 1; i <= n; ++i) {
h[i] = real_d[i];
}
return d[D] != kInf;
}
void get_fmcm() {
int maxFlow = 0, flowCost = 0;
Bellman(S, h);
while (Dijkstra(S, D)) {
int minFlow = kInf;
for (auto node = D; node != S; node = p[node]) {
minFlow = min(minFlow, cap[p[node]][node] - flow[p[node]][node]);
}
if (minFlow > 0) {
maxFlow += minFlow;
flowCost += minFlow * real_d[D];
for (auto node = D; node != S; node = p[node]) {
flow[p[node]][node] += minFlow;
flow[node][p[node]] -= minFlow;
}
}
}
cout << flowCost << "\n";
}
int main() {
read_input();
get_fmcm();
return 0;
}