Pagini recente » Cod sursa (job #3254224) | Cod sursa (job #3210648) | Cod sursa (job #2479446) | Cod sursa (job #889566) | Cod sursa (job #2961849)
#include <queue>
#include <vector>
#include <climits>
#include <fstream>
using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
#define N_MAX 351
#define INFINITY INT_MAX
int N, M, src, dest;
vector<int> neighbors[N_MAX];
// Min Cost for Max Flow
int min_cost, max_flux;
int parent[N_MAX], capacity[N_MAX][N_MAX], cost[N_MAX][N_MAX];
// Bellman Ford
int old_dist[N_MAX];
// Dijkstra
int dist[N_MAX], real_cost[N_MAX];
bool dijkstra() {
auto comparator = [](int lhs, int rhs) {
return dist[lhs] > dist[rhs];
};
static auto heap = priority_queue<int,
vector<int>, decltype(comparator)>(comparator);
for (int i = 1; i <= N; ++i) {
dist[i] = INFINITY;
}
dist[src] = 0;
real_cost[src] = 0;
heap.push(src);
while (!heap.empty()) {
int node = heap.top();
heap.pop();
for (auto neigh : neighbors[node]) {
// the capacity is exhausted or
// there is no residual flow to push back
if (capacity[node][neigh] == 0)
continue;
int new_dist = dist[node] + cost[node][neigh]
+ old_dist[node] - old_dist[neigh];
if (dist[neigh] > new_dist) {
dist[neigh] = new_dist;
real_cost[neigh] = real_cost[node] + cost[node][neigh];
parent[neigh] = node;
heap.push(neigh);
}
}
}
return dist[dest] != INFINITY;
}
void bellmanFord() {
bool inQueue[N_MAX];
queue<int> queue;
for (int i = 1; i <= N; ++i) {
old_dist[i] = INFINITY;
inQueue[i] = false;
}
queue.push(src);
old_dist[src] = 0;
inQueue[src] = true;
while (!queue.empty()) {
int node = queue.front();
queue.pop();
inQueue[node] = false;
for (auto neigh : neighbors[node]) {
// this is an actual edge, not a residual one
if (capacity[node][neigh] == 0)
continue;
// this cost distance is not much better than the previously one
if (old_dist[neigh] <= old_dist[node] + cost[node][neigh])
continue;
old_dist[neigh] = old_dist[node] + cost[node][neigh];
// the neigh is already in queue
if (inQueue[neigh])
continue;
inQueue[neigh] = true;
queue.push(neigh);
}
}
}
int main() {
int x, y, c, z, min_flux;
fin >> N >> M >> src >> dest;
for (int i = 0; i < M; ++i) {
fin >> x >> y >> c >> z;
neighbors[x].push_back(y);
neighbors[y].push_back(x);
capacity[x][y] = c;
cost[x][y] = z;
cost[y][x] = -z;
}
bellmanFord();
for (min_cost = 0, max_flux = 0; dijkstra();) {
min_flux = INFINITY;
for (int i = 1; i <= N; ++i) {
old_dist[i] = real_cost[i];
}
for (int node = dest; node != src; node = parent[node]) {
min_flux = min(min_flux, capacity[parent[node]][node]);
}
for (int node = dest; node != src; node = parent[node]) {
capacity[parent[node]][node] -= min_flux;
capacity[node][parent[node]] -= min_flux;
}
max_flux += min_flux;
min_cost += min_flux * real_cost[dest];
}
fout << min_cost;
return 0;
}