Pagini recente » Cod sursa (job #2459420) | Cod sursa (job #2763297) | Clasament oji_bv_2022 | Cod sursa (job #3003915) | Cod sursa (job #3136697)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
const int NMAX = 355;
const int INF = 1e9;
int n, m, src, dest;
int cost[NMAX][NMAX];
int cap[NMAX][NMAX], flow[NMAX][NMAX];
vector<pair<int, int>> G[NMAX], invG[NMAX];
int prevNode[NMAX]; // for bfs (negative if inverse edge)
int dist[NMAX];
// returns whether we reached the end
bool bellmanFord() {
for (int i = 1; i <= n; i++) {
prevNode[i] = 0;
dist[i] = INF;
}
queue<int> Q; // TODO check if it's in the queue before pushing (optimization)
dist[src] = 0;
Q.push(src);
while (!Q.empty()) {
int vertex = Q.front();
Q.pop();
// normal edges
for (auto neigh: G[vertex])
if (dist[vertex] + neigh.second < dist[neigh.first] && flow[vertex][neigh.first] != cap[vertex][neigh.first]) { // unvisited vertex, and unsaturated edge
dist[neigh.first] = dist[vertex] + neigh.second;
prevNode[neigh.first] = vertex;
Q.push(neigh.first);
}
// inverse edges
for (auto neigh: invG[vertex])
if (dist[vertex] - neigh.second < dist[neigh.first] && flow[neigh.first][vertex] != 0) { // we'll remove flow from here
// TODO shouldnt dist be subtracted here?
dist[neigh.first] = dist[vertex] - neigh.second;
prevNode[neigh.first] = -vertex;
Q.push(neigh.first);
}
}
return dist[dest] != INF;
}
int main() {
fin >> n >> m >> src >> dest;
for (int i = 1; i <= m; i++) {
int u, v, ca, co;
fin >> u >> v >> ca >> co;
G[u].push_back({v, co});
invG[v].push_back({u, co});
cap[u][v] = ca;
cost[u][v] = co;
flow[u][v] = 0;
}
int totalCost = 0;
while (bellmanFord()) {
int curr = dest;
int toAdd = cap[prevNode[dest]][dest] - flow[prevNode[dest]][dest];
while (curr != src) {
int a = prevNode[curr], b = curr;
if (a < 0) { // inverse edge
toAdd = min(toAdd, flow[b][-a]);
curr = -a;
}
else {
toAdd = min(toAdd, cap[a][b] - flow[a][b]);
curr = a;
}
}
toAdd = 1; // EVIL
curr = dest;
while (curr != src) {
int a = prevNode[curr], b = curr;
if (a < 0) {
flow[b][-a] -= toAdd;
totalCost -= toAdd * cost[b][-a]; // TODO subtract or add?
curr = -a;
}
else {
flow[a][b] += toAdd;
totalCost += toAdd * cost[a][b];
curr = a;
}
}
}
int totalFlow = 0;
for (auto v: G[src])
totalFlow += flow[src][v.first];
fout << totalCost;
return 0;
}