Pagini recente » Cod sursa (job #1258545) | Cod sursa (job #3288966) | Cod sursa (job #2683440) | Cod sursa (job #2425543) | Cod sursa (job #3253645)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
#include <cassert>
using namespace std;
#define MAXN 355
#define INF 0x3f3f3f3f
int N, M, S, D;
int C[MAXN][MAXN], Cst[MAXN][MAXN];
vector<int> con[MAXN];
int F = 0, FCst = 0;
int old_d[MAXN], d[MAXN], real_d[MAXN], p[MAXN];
char inQ[MAXN];
queue<int> Q;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> H;
bool dijkstra() {
memset(d, 0x3f, sizeof(d));
d[S] = 0;
real_d[S] = 0;
H.push({d[S], S});
while (!H.empty()) {
int cst = H.top().first, nod = H.top().second;
H.pop();
if (d[nod] != cst) continue;
for (int it : con[nod]) {
if (C[nod][it]) {
int new_d = d[nod] + Cst[nod][it] + old_d[nod] - old_d[it];
if (new_d < d[it]) {
d[it] = new_d;
real_d[it] = real_d[nod] + Cst[nod][it];
p[it] = nod;
H.push({d[it], it});
}
}
}
}
memcpy(old_d, real_d, sizeof(real_d));
if (d[D] == INF) return false;
int Min = INF;
for (int aux = D; aux != S; aux = p[aux]) {
Min = min(Min, C[p[aux]][aux]);
}
F += Min;
FCst += Min * real_d[D];
for (int aux = D; aux != S; aux = p[aux]) {
C[p[aux]][aux] -= Min;
C[aux][p[aux]] += Min;
}
return true;
}
bool bellmanFord() {
memset(old_d, 0x3f, sizeof(old_d));
old_d[S] = 0;
Q.push(S);
inQ[S] = 1;
while (!Q.empty()) {
int i = Q.front();
Q.pop();
inQ[i] = 0;
for (int it : con[i]) {
if (C[i][it]) {
if (old_d[i] + Cst[i][it] < old_d[it]) {
old_d[it] = old_d[i] + Cst[i][it];
if (!inQ[it]) {
inQ[it] = 1;
Q.push(it);
}
}
}
}
}
return old_d[D] != INF;
}
int main() {
ifstream in("fmcm.in");
ofstream out("fmcm.out");
in >> N >> M >> S >> D;
for (int i = 0; i < M; ++i) {
int x, y, capacity, cost;
in >> x >> y >> capacity >> cost;
C[x][y] = capacity;
Cst[x][y] = cost;
Cst[y][x] = -cost;
con[x].push_back(y);
con[y].push_back(x);
}
if (bellmanFord()) {
while (dijkstra());
}
out << FCst << '\n';
return 0;
}